React 中 setState的对象、数组的操作

7,812 阅读1分钟

先看以下代码

import {useState} from 'react'

function App() {
  let [count, setCount] = useState(0);
  let [arr, setArr] = useState([]);

  const handleClick = () => {
      count += 1;
      setCount(count)
      console.log(count)
  }
  const getCount = ()=>{
      setTimeout(() => {
          console.log(count)   // 先按getCount 按钮 再按Add按钮 输出的是3s前的数字
      }, 3000)
  }


  const handleArrClick = ()=>{
      arr.push(Math.random())
      // setArr(arr)  此处这种方式 页面是不刷新的,react hook更新数组不是往原数组里添加项目,而是要用一个新数组完全替代
      setArr([...arr])
      console.log(arr)
  }

  return (
      <>
        <h2>{count}</h2>
        <button onClick={handleClick}>Add</button>
        <button onClick={getCount}>getCount</button>
          <br/>
          {
              arr.map((item,index)=>{
                  return <h2 key={index}>{item}</h2>
              })
          }
        <button onClick={(e)=>handleArrClick(e)}>Add arr</button>
      </>
  );
}
export default App;

react hook只用了useState钩子函数来给函数(无状态)组件添加状态,状态值为什么不是最新的?其原因是**「Capture Value」** 特性;

援引文章 精读《useEffect 完全指南》 中对 Capture Value 概念的解释:「每次 Render 的内容都会形成一个快照并保留下来,因此当状态变更而 Rerender 时,就形成了 N 个 Render 状态,而每个 Render 状态都拥有自己固定不变的 Props 与 State」

解决方案可参考

React Hooks: Get prevState values

下面是更改数据的一些小技巧:

 // 1、修改object中某项
 
this.setState({
  object: {...object, key: value}
});
  // 2、删除数组首位
 
array.splice(0, 1);
this.setState({
  array
});
  // 3、删除数组尾部
 
array.splice(array.length - 1);
this.setState({
  array
});
  // 4、删除数组任意一项
 
array.splice(index, 1);
this.setState({
  array
});
  // 5、数组尾部添加一项
 
this.setState({
  array: [...array, item]
});
 //  6、数组头部添加一项
 
this.setState({
  array: [item, ...array]
});
  7、数组任意位置添加一项
 
array.splice(index, 0, item);
this.setState({
  array
});
 // 8、修改数组中任意一项中值
 
function updateArrayItem(index, key, value) {
  this.setState({
    array: array.map((item, _index) => _index == index ? {...item, [key]: value} : item)
  });
}
//  9、复杂类型修改
 
this.setState(prevState => return newState);