首页 > 解决方案 > 无法使用 useState 实时更新初始状态

问题描述

首先,如果我不能正确解释这个问题,我会道歉。我也知道 useState 是异步的。我试图尽可能地简化代码。所以基本上,在下面的代码中,我有一个方法 handleSubCatChange ,它在 onChange 事件上运行。每当将复选框保存时,subs:[]在初始状态中,需要由复选框中的值填充。handleSubCatChange 方法检查子数组的元素是否已经在 selectedValues 中。

我有三个 console.logs ,如果我一个一个地单击所有三个复选框,最后一个 console.log('0002') 表明 selectedValues 数组立即更新。

console.log('000'),在第一次单击和单击第二个复选框时显示空 selectedValues 状态,记录第一个复选框值,即苹果,当单击第三个复选框时,第二个复选框值是香蕉已记录。第三个 console.log('0001') 更慢,只有在单击所有复选框后,它才会显示数组中的第一个是苹果的。我也尝试过使用 JSON.stringify,结果略有不同。{JSON.stringify(selectedValues)},实时更新,但 {JSON.stringify(values.subs)} 仅在单击所有三个复选框时显示前两个元素 apple 和banana。

我在初始状态中有更多属性,但为简单起见,我只提到了标题和子项。复选框是表单元素的一部分,因此我需要实时更新 subs:[] 以便 II 可以提交具有其他值的表单。我试过 useEffect 但没有运气。请帮忙。

import React,{useState} from 'react';

const initialState={ title:'glasses', subs:[],    }

const subarray=['apple','banana','orange']

const ProductCreate=()=>{

const [values,setValues]=useState(initialState); const[selectedValues,setSelectedValues]=useState([]);

useEffect(()=>{
    },[selectedValues])

const handleSubCatChange=(checkedName)=>{

if(selectedValues.includes(checkedName)){
    setSelectedValues(selectedValues.filter((c)=> c!=(checkedName)))
}
  else{ 
    setSelectedValues([...selectedValues,checkedName])
}
    setValues({...values,subs:selectedValues}) 
console.log('0000',selectedValues); console.log('0001',values.subs);}     
    )}
return( <>
 
{JSON.stringify(values.subs)}
{JSON.stringify(selectedValues)}


{subarray.map((s)=>
 <div key={index} >
  {console.log('0002',selectedValues)}
     <input type="checkbox" 
     value={s} 
     onChange={()=>handleSubCatChange(s)}
     />
 </div>
}
</>     )
}

标签: javascriptreactjsreact-hooks

解决方案


如果您希望values状态与selectedValues状态同步,请正确使用useEffect钩子。

仅使用handleSubCatChange函数来更改 的状态selectedValues

const handleSubCatChange = (checkedName) => {
    if (selectedValues.includes(checkedName)) {
      setSelectedValues(selectedValues.filter((c) => c !== checkedName));
    } else {
      setSelectedValues([...selectedValues, checkedName]);
    }
  };

并且只有在状态改变时才使用useEffect钩子来改变状态。valuesselectedValues

useEffect(() => {
    setValues({ ...values, subs: selectedValues });
    console.log("0000", selectedValues);
    console.log("0001", values.subs);
  }, [selectedValues]);

在CodeSandbox工作演示。

编辑:

selectedValues初始化期间添加初始值。更改为:

const [selectedValues, setSelectedValues] = useState(['banana']);

添加checked到输入以预选复选框。

checked={selectedValues.includes(s)}

仔细看演示。


推荐阅读