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

标签 javascript reactjs functional-programming components

我是 React 新手,对功能组件的生命周期感到非常困惑。 假设我有许多类型的输入:复选框、a、b、c 和 d。它们的值为 a、b、c 和 d。

const OnBoarding = () => {
  const [isChecked, setIsChecked] = useState({
    a: false,
    b: false,
    c: false,
    d: false
  });
  
  const [allCheckedItems, setAllCheckedItems] = useState([]);
  
  //Write function that pushes checked value to state array when clicked
  const onChecked = e => {
    setIsChecked({
      ...isChecked,
      [e.target.value]: e.target.checked
    });
    const all = Object.keys(isChecked).filter(function(key){
      return isChecked[key] === true;
    });
    console.log("all items that are TRUE : " + all);
    setAllCheckedItems([all]);
    console.log("allCheckedItems : " + allCheckedItems);
  };
  
  useEffect(() => {
    console.log(isChecked);
  });
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

我有一个功能组件,其状态类型是一个对象,具有许多属性,所有属性都是 bool 值,如下所示:

const [isChecked, setIsChecked] = useState({
  a: false,
  b: false,
  c: false,
  d: false
})

我还有一个状态,它是一个数组,我们称之为allCheckedItems,它应该是isChecked所有键的数组。强> 设置为 true。

const [allCheckedItems, setAllCheckedItems] = useState([]);

使用 onChecked 函数,当选中复选框时,isChecked 对象中的值将设置为 true

我调用 useEffect(),在其中编写了一个过滤函数来过滤所有为 true 的属性。所有设置为 true 的属性都存储在名为 "all" 的数组中。

当我必须更新数组 allCheckedItems 的状态时,我的问题就出现了。如果我在 useEffect 钩子(Hook)中写入:

setAllCheckedItems([all]);

我遇到了无限循环。如果我将其写入我的 onChecked 函数中,则每当我单击复选框时,我在控制台中登录的 allCheckedItems 的状态都是一次单击的“晚”。 就像,我点击检查“a”并记录:

[]

然后我单击“b”,它会记录:

[a]

然后我单击“c”,它会记录:

[a, b]

我希望当我选中一个框时,两个状态都会更新,并且 allItemsChecked 会立即记录所有选中的项目... 有人可以向我解释这种行为吗?这让我头疼好几天了。

最佳答案

useEffect 钩子(Hook)给您带来无限循环的原因是,当未提供第二个参数时,useEffect 会在每次渲染后触发。官方react上是这么说的documentation对于 React hooks,如果第二个参数中的值没有改变,组件将跳过效果的应用。

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

useEffect(() => {
  setAllCheckedItems([all]);
}, [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 状态的副本,并使用新值更新该副本。此外,我们使用该副本返回已检查的 key 。之后,我们更新各自的状态。

关于javascript - 如何在React功能组件中立即更新状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59633330/

相关文章:

javascript - JS 解释器 - 更改 “this” 上下文

javascript - 创建通用自定义组件 React

scala - 在 Scala 中,通过名称参数调用的函数与将另一个函数作为参数的函数不同吗?

scala - 如何以函数式编程风格在 Scala 中创建列表列表

Python:args -> *args 的一些函数(类似于 functools 中的函数)

javascript - 如何通过react router传递和使用查询参数?

javascript - 如何在 javascript 中捕获 jquery 自定义事件

php - iPhone强制下载文件?

css - 将css文件导入特定组件 react 应用程序

java - 在 Heroku 上部署 Spring Boot + React JS 应用程序时出错 - 应用程序崩溃