【问题标题】:How to set multiple states using react hooks如何使用反应钩子设置多个状态
【发布时间】:2020-06-03 23:24:46
【问题描述】:

我在我的一个反应组件中设置多个状态时遇到问题。我的最终目标是:我首先要设置我的“casesData”状态(见下文),以便在每个后续点击事件中将“selected”的值设置为“true”或“false”。然后我想通过'casesData'映射找到'selected:true',然后将'case'的值添加到'chosenCases'。所以最后 'chosenCases' 可能看起来像:['case1', 'case2'] 只要他们各自在 'casesData' 中的对象等于 'selected: true'。

我的初始状态是这样设置的:

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

我通过映射我的“casesData”状态将内容呈现到屏幕上。然后我从 onClick 调用一个函数来开始更新我的状态:

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>
                );
           }
       )}
    </>
);

这是应该更新我的两个状态的函数。

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);
};

如果我在运行上述函数后将状态记录到控制台,我会看到“casesData”得到正确更新,但“chosenCases”总是落后一步。例如,'chosenCases' 在函数第一次运行时保持为空,但在第二次运行时设置(例如 ['case2'] 但数据将反映之前的函数调用)。

任何帮助将不胜感激。我想知道最合适的设置方式。

【问题讨论】:

    标签: javascript reactjs react-hooks setstate


    【解决方案1】:

    最简单的做法是将新的casesData 存储在一个变量中,这样您就不必等待新的渲染才能看到新的状态:

    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 这样的派生状态,并在渲染时注意找出选定的情况。这将使您的代码更容易推理,因为您不必担心两个状态的处置。

    【讨论】:

      猜你喜欢
      • 2021-08-02
      • 2020-03-19
      • 1970-01-01
      • 2020-11-30
      • 2022-10-17
      • 2020-04-01
      • 2020-10-02
      • 2020-06-12
      相关资源
      最近更新 更多