簡體   English   中英

如何使用反應鈎子設置多個狀態

[英]How to set multiple states using react hooks

我在我的一個反應組件中設置多個狀態時遇到問題。 我的最終目標是:我首先想設置我的“casesData”state(見下文),以便在每個后續點擊事件中可以將“selected”的值設置為“true”或“false”。 然后我想通過'casesData'找到map找到'selected:true'的位置,然后將'case'的值添加到'chosenCases'。 所以最后 'chosenCases' 可能看起來像:['case1', 'case2'] 只要它們各自在 'casesData' 中的對象等於 'selected: true'。

我最初的 state 是這樣設置的:

const [chosenCases, setChosenCases] = useState([]);
const [casesData, setCasesData] = useState([
    {
        case: 'Case1',
        description: 'some description',
        selected: false,
    },
    {
        case: 'Case2',
        description: 'some description',
        selected: false,
    },
]);

我通過映射我的“casesData”state 將內容呈現到屏幕上。 然后我從 onClick 調用 function 開始更新我的狀態:

return (
    <>
       {casesData.map(
           (
               casex  // casex because 'case' is a reserved word
           ) => {
               return (
                   <span
                       onClick={selectCase}
                       data-case={casex.case}
                   >
                       <p>{casex.case}</p>
                       <p>{casex.description}</p>
                   </span>
                );
           }
       )}
    </>
);

這是 function 應該更新我的兩個狀態。

const selectCase = (event) => {
    console.log(event.target.getAttribute('data-case'));  // e.g. 'case2'

    setCasesData(
        [...casesData].map((object) => {
            if (
                object.case.toLowerCase() ===
                event.target.getAttribute('data-case').toLowerCase()
            ) {
                return {
                    ...object,
                    selected: !object.selected,
                };
            } else return object;
        })
    );

    let newArray = [];
    casesData.map((object) => {
        if (object.selected === true) {
            newArray.push(object.case.toLowerCase());
        }
    });
    setChosenCases(newArray);
};

如果我在運行上述 function 后將狀態記錄到控制台,我會看到“casesData”得到正確更新,但“chosenCases”總是落后一步。 例如,'chosenCases' 在第一次運行 function 時保持為空,但在第二次運行時設置(例如 ['case2'] 但數據將反映之前的 function 調用)。

任何幫助將非常感激。 我想知道最合適的設置方式。

最簡單的做法是將新的casesData存儲在一個變量中,這樣您就不必等待新的渲染才能看到新的 state:

const selectCase = (event) => {
    console.log(event.target.getAttribute('data-case'));  // e.g. 'case2'

    const newCasesData = casesData.map((object) => 
        (object.case.toLowerCase() === event.target.getAttribute('data-case').toLowerCase())
            ? {
                ...object,
                selected: !object.selected,
            } 
            : object
    )

    setCasesData(newCasesData);

    setChosenCases(
        newCasesData
            .filter(obj => obj.selected)
            .map(obj => obj.case.toLowerCase())
    );
};

您可能還想重新考慮需要派生的chosenCases (例如 selectedCases),並在渲染時注意找出選定的案例。 這將使您的代碼更易於推理,因為您不必擔心兩塊 state 的配置。

暫無
暫無

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

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