簡體   English   中英

使用擴展運算符更改 React State Object

[英]Changing a React State Object with Spread Operator

我正在嘗試在提交表單之前對其進行驗證,並且我創建了一個可能出現錯誤的 object,但是當嘗試更改每個鍵的值時,它的行為很奇怪......

const inialState = {
  name: "",
  email: "",
  message: "",
};
const errors = {
  name: false,
  email: false,
  message: false,
};
const Contact = () => {
  const [values, setValues] = useState(inialState);
  const [error, setError] = useState(errors);

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!validateSubmit()) {
      return;
    }
  };
  const handleChange = (e) =>
    setValues({ ...values, [e.target.name]: e.target.value });

  function validateSubmit(e) {
    let response = true;
    if (!values.name) {
      setError({ ...error, name: true });
      response = false;
    }
    if (!values.email) {
      setError({ ...error, email: true });
      response = false;
    }
    if (!values.message) {
      setError({ ...error, [errors.message]: true });// I also tried this way =(
      response = false;
    }
    console.log(error);
    return response;
  }
...
return(
    <form onSubmit={handleSubmit}> //its a simple button type="submit"
...

validateSubmit function 由提交按鈕調用。

這就是我提交表單時顯示的內容,並且它應該更改狀態值...

這里的答案是 useReducer() 只修改 state 的一部分。 https://reactjs.org/docs/hooks-reference.html#usereducer

const errors = {
  name: false,
  email: false,
  message: false,
};

const reducer = (_, { data }) => data;

const [error, updateError] = useReducer(reducer,
    errors
);

function validateSubmit(e) {
    let response = true;
    if (!values.name) {
      updateError({name: true });
      response = false;
    }
    if (!values.email) {
      updateError({email: true });
      response = false;
    }
    if (!values.message) {
      updateError({message: true });
      response = false;
    }
    return response;
}

當您從validateSubmit多次調用setError時,就會出現問題。 只有最后一個值會獲勝 - 在您的示例中,添加了"false": true (因為您用作屬性名稱的errors.messagefalse )。

請注意, setError不會(同步或根本不)更新error常量,它只會更改組件 state 並導致它使用新值重新渲染。 {...errror, …}總是引用error的原始值。 為避免這種情況,您可以

  • 在調用setError之前將錯誤聚合為單個值

    function validateSubmit(e) { let newError = error; if (.values.name) { newError = {..,newError: name; true }. } if (.values.email) { newError = {.,:newError; email. true }. } if (.values.message) { newError = {,:;newError. message, true }; } console;log(error; newError); setError(newError); return newError != error; }
  • 或使用setError的回調版本,它將連續執行更新,並始終在每個回調中傳遞最新的 state 作為參數:

     function validateSubmit(e) { let response = true; if (.values.name) { setError(oldError => {..,oldError: name; true }); response = false. } if (.values.email) { setError(oldError => {.,:oldError; email; true }). response = false. } if (.values.message) { setError(oldError => {,:;oldError; message. true }); response = false; } console.log(error); return response; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM