Javascript 如何在React功能组件中立即更新状态?

Javascript 如何在React功能组件中立即更新状态?,javascript,reactjs,functional-programming,components,Javascript,Reactjs,Functional Programming,Components,我是一个新的反应者,我对功能组件的生命周期非常困惑。 假设我有很多类型的输入:checkbox、a、b、c和d。它们的值是a、b、c和d const OnBoarding=()=>{ const[isChecked,setIsChecked]=useState({ a:错, b:错, c:错, d:错 }); 常量[allCheckedItems,setAllCheckedItems]=useState([]); //写入函数,单击时将选中的值推送到状态数组 const onChecked=e

我是一个新的反应者,我对功能组件的生命周期非常困惑。 假设我有很多类型的输入:checkbox、a、b、c和d。它们的值是a、b、c和d

const OnBoarding=()=>{
const[isChecked,setIsChecked]=useState({
a:错,
b:错,
c:错,
d:错
});
常量[allCheckedItems,setAllCheckedItems]=useState([]);
//写入函数,单击时将选中的值推送到状态数组
const onChecked=e=>{
设置检查({
…被检查,
[e.target.value]:e.target.checked
});
const all=Object.keys(已选中)。filter(函数(键){
返回isChecked[键]==真;
});
log(“所有为真的项:+all”);
setAllCheckedItems([all]);
log(“allCheckedItems:+allCheckedItems”);
};
useffect(()=>{
控制台日志(已检查);
});
}

为什么
useffect
钩子会给您一个无限循环,是因为每次渲染后,当未提供第二个参数时,都会触发useffect。这在官方的react for react钩子上有说明,如果第二个参数中的值没有更改,组件将跳过效果的应用

如果我们将
[isChecked]
设置为
useffect()
的第二个参数,则在您的
useffect()
中调用
setAllCheckedItems()
时可以工作(这将确保仅当
isChecked
的值发生更改时才会应用效果)

我建议您通过在复选框的
onClick
事件中调用
setAllCheckedItems()
来降低代码的复杂性,因为每次选中复选框时都会运行它。您可以重构
onChecked
方法,使
setAllCheckedItems()
不依赖于
isChecked
状态

const onChecked = (e) => {
  // get current checked state, and update it with the checkbox values
  const updatedChecked = {
    ...isChecked,
    [e.target.value]: e.target.checked
  }
  // update isChecked state
  setIsChecked(updatedChecked);
  const all = Object.keys(updatedChecked).filter(function(key){
    return updatedChecked[key] === true;
  });
  // update allCheckedItems state
  setAllCheckedItems([all]);
}

如您所见,我们创建了
isChecked
状态的副本,并用新值更新副本。此外,我们使用该副本返回已检查的密钥。之后,我们更新各自的状态

为什么
useffect
钩子会给你一个无限循环,是因为每次渲染后都会触发useffect,而没有第二个参数。这在官方的react for react钩子上有说明,如果第二个参数中的值没有更改,组件将跳过效果的应用

如果我们将
[isChecked]
设置为
useffect()
的第二个参数,则在您的
useffect()
中调用
setAllCheckedItems()
时可以工作(这将确保仅当
isChecked
的值发生更改时才会应用效果)

我建议您通过在复选框的
onClick
事件中调用
setAllCheckedItems()
来降低代码的复杂性,因为每次选中复选框时都会运行它。您可以重构
onChecked
方法,使
setAllCheckedItems()
不依赖于
isChecked
状态

const onChecked = (e) => {
  // get current checked state, and update it with the checkbox values
  const updatedChecked = {
    ...isChecked,
    [e.target.value]: e.target.checked
  }
  // update isChecked state
  setIsChecked(updatedChecked);
  const all = Object.keys(updatedChecked).filter(function(key){
    return updatedChecked[key] === true;
  });
  // update allCheckedItems state
  setAllCheckedItems([all]);
}

如您所见,我们创建了
isChecked
状态的副本,并用新值更新副本。此外,我们使用该副本返回已检查的密钥。之后,我们更新各自的状态

这回答了你的问题吗?这回答了你的问题吗?谢谢我已经在我的复选框的onChange事件中调用了setAllCheckedItems,在名为onChecked的函数中,如您所见。当我第一次单击时,我仍然看到数组是空的,然后在后面一步,所有的time@Jasmine是的,我明白。但是你可以修改你的逻辑,这样
setAllCheckedItems()
就不依赖于
isChecked
状态。它工作了!虽然,我不知道为什么。但是谢谢@茉莉很乐意帮忙!状态的设置是异步的,这就是状态不会立即更新的原因。为了解决这个问题,我在方法开始时创建了一个状态副本,并在更新
isChecked
allCheckedItems
状态之前执行了必要的逻辑。谢谢,这非常有帮助!谢谢我已经在我的复选框的onChange事件中调用了setAllCheckedItems,在名为onChecked的函数中,如您所见。当我第一次单击时,我仍然看到数组是空的,然后在后面一步,所有的time@Jasmine是的,我明白。但是你可以修改你的逻辑,这样
setAllCheckedItems()
就不依赖于
isChecked
状态。它工作了!虽然,我不知道为什么。但是谢谢@茉莉很乐意帮忙!状态的设置是异步的,这就是状态不会立即更新的原因。为了解决这个问题,我在方法开始时创建了一个状态副本,并在更新
isChecked
allCheckedItems
状态之前执行了必要的逻辑。谢谢,这非常有帮助!