开发者问题收集

REACT 无法在 onKeyPress 上读取 null 的属性“value”

2021-04-21
188

我有一个名为 EmailSubscribe 的反应组件,它获取文本输入框的值并通过提取请求发送它。我已将两个元素保存到变量 emailInput 和 emailContainer 中,但是,我收到以下错误消息:

Uncaught TypeError: Cannot read property 'value' of null
    at onKeyPress

我使用其他组件时没有遇到此问题,如果每次需要时用 document.querySelector('XXXX') 替换 emailInput 和 emailContainer,我的代码就可以正常工作,但这不是一种干净的方法。知道我为什么会收到此错误消息吗?

App.js

import ResultsPage from "./pages/ResultsPage/results";
import Header from "./components/Header";
import EmailSubscribe from "./components/EmailSubscribe";

function App() {
  return (
    <div className="App">
      <Header />
      <ResultsPage />
      <EmailSubscribe />
    </div>
  );
}

export default App;

EmailSubscribe.jsx

function EmailSubscribe() {
  const emailContainer = document.querySelector(".email-container");
  const emailInput = document.querySelector(".email-input");

  const isValidEmail = (email) => {
    var validEmailRegex = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
    return validEmailRegex.test(email);
  };

  const resetEmailSubscribe = (newValue, newPlaceholder, isErrorMessage) => {
    emailInput.value = newValue;
    emailInput.placeholder = newPlaceholder;
    if (isErrorMessage) {
      emailInput.classList.add("placeholderColorOrange");
    } else {
      emailInput.classList.remove("placeholderColorOrange");
    }
  };

  const emailSubscribePOST = (email) => {
    if (email.trim() == "") {
      resetEmailSubscribe("", "Please enter your email address", true);
    } else if (!isValidEmail(email)) {
      resetEmailSubscribe("", "Invalid email address", true);
    } else {
      fetch("http://127.0.0.1:5000/subscribe", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({ email: email }),
      })
        .then((res) => res.json())
        .then((res) => {
          if (res.message == "Email sent successfully") {
            emailContainer.innerHTML =
              "<p class='email-thankyou'>Thank you for subscribing!</p>";
          } else if (res.message == "Email already registered") {
            resetEmailSubscribe("", res.message, true);
          }
        });
    }
  };

  return (
    <div class="email-container">
      <input
        type="text"
        className="email-input"
        placeholder="Register or log in"
        onKeyPress={(e) =>
          e.key === "Enter" && emailSubscribePOST(emailInput.value)
        }
      />
      <button
        type="button"
        className="email-submit-btn btn"
        onClick={() => {
          emailSubscribePOST(emailInput.value);
        }}
      >
        Submit
      </button>
    </div>
  );
}

export default EmailSubscribe;
2个回答

一般来说,不要在 React 中使用 document.get... 访问项目。在 React 中,您可以对正在做的事情进行状态控制。

function EmailSubscribe() {
  const [input, setInput] = useState("");
  const [placeholder, setPlaceholder] = useState("Register or log in");
  const [hasSubscribed, setHasSubscribed] = useState(false);
  const [hasErrorMessage, setHasErrorMessage] = useState(false);

  const isValidEmail = (email) => {
    var validEmailRegex = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
    return validEmailRegex.test(email);
  };

  const resetEmailSubscribe = (newValue, newPlaceholder, hasErrorMessage) => {
    setInput(newValue);
    setPlaceholder(newPlaceholder);
    setHasErrorMessage(hasErrorMessage);
  };

  const emailSubscribePOST = (email) => {
    if (email.trim() == "") {
      resetEmailSubscribe("", "Please enter your email address", true);
    } else if (!isValidEmail(email)) {
      resetEmailSubscribe("", "Invalid email address", true);
    } else {
      fetch("http://127.0.0.1:5000/subscribe", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({ email: email }),
      })
        .then((res) => res.json())
        .then((res) => {
          if (res.message == "Email sent successfully") {
            setHasSubscribed(true)
          } else if (res.message == "Email already registered") {
            resetEmailSubscribe("", res.message, true);
          }
        });
    }
  };

  return (
    <div class="email-container">
      {hasSubscribed ? 
        <p class='email-thankyou'>Thank you for subscribing!</p>
        :
        <input
          type="text"
          className={hasErrorMessage ? "placeholderColorOrange" : ""}
          placeholder={emailInputPlaceholder}
          onChange={e => setInput(e.target.value)}
          value={input}
          onKeyPress={(e) =>
            e.key === "Enter" && emailSubscribePOST(input)
          }
        />
        <button
          type="button"
          className="email-submit-btn btn"
          onClick={() => {
            emailSubscribePOST(input);
          }}
        >
        Submit
        </button>
      }
    </div>
  );
}

export default EmailSubscribe;
FireFighter
2021-04-21

这里的主要问题是您的输入文本框中没有 value 属性。请尝试将“value”属性添加到输入文本并使用 onChange 设置状态,如下所示:

<input
        type="text"
        className="email-input"
        placeholder="Register or log in"
        value={emailInput}
        onChange={(e)=>setEmailInput(e.value)
        onKeyPress={(e) =>
          e.key === "Enter" && emailSubscribePOST(emailInput)
        }
      />
      <button
        type="button"
        className="email-submit-btn btn"
        onClick={() => {
          emailSubscribePOST(emailInput);
        }}
      >

它应该可以工作。

Reshmi Agarwal
2021-04-21