react中useState改变值不渲染
React中默认浅监听,当State值为对象时,栈中存的是对象的引用(地址),setState改变的是堆中的数据
所以此时 setArr(arr) 后,栈中的地址还是原地址,React浅监听到地址没变,故会认为State并未改变,故没有重渲染页面
解决的办法
示例如下:
利用ES6的拓展符
const [arr, setArr] = useState([])
setArr([...arr])
react踩坑 useState的两次渲染
问题背景,函数组件中使用useState后,console.log发现组件重复渲染。
一开始我以为是useState的问题,经查验,发现是index.tsx里<React.StrictMode>的坑
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
以下内容,摘自react官网,如果你很忙可以不看!总之,渲染两次没事,生产模式下不会这样。
StrictMode 目前有助于:
- 识别不安全的生命周期
- 关于使用过时字符串 ref API 的警告
- 关于使用废弃的 findDOMNode 方法的警告
检测意外的副作用
检测过时的 context API
检测意外的副作用
从概念上讲,React 分两个阶段工作:
渲染 阶段会确定需要进行哪些更改,比如 DOM。在此阶段,React 调用 render,然后将结果与上次渲染的结果进行比较。
提交 阶段发生在当 React 应用变化时。(对于 React DOM 来说,会发生在 React 插入,更新及删除 DOM 节点的时候。)在此阶段,React 还会调用 componentDidMount 和 componentDidUpdate 之类的生命周期方法。
提交阶段通常会很快,但渲染过程可能很慢。因此,即将推出的 concurrent 模式 (默认情况下未启用) 将渲染工作分解为多个部分,对任务进行暂停和恢复操作以避免阻塞浏览器。这意味着 React 可以在提交之前多次调用渲染阶段生命周期的方法,或者在不提交的情况下调用它们(由于出现错误或更高优先级的任务使其中断)。
渲染阶段的生命周期包括以下 class 组件方法:
constructor
componentWillMount
(orUNSAFE_componentWillMount
)componentWillReceiveProps
(orUNSAFE_componentWillReceiveProps
)componentWillUpdate
(orUNSAFE_componentWillUpdate
)getDerivedStateFromProps
shouldComponentUpdate
render
setState
更新函数(第一个参数)
因为上述方法可能会被多次调用,所以不要在它们内部编写副作用相关的代码,这点非常重要。忽略此规则可能会导致各种问题的产生,包括内存泄漏和或出现无效的应用程序状态。不幸的是,这些问题很难被发现,因为它们通常具有非确定性。
严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。
通过故意重复调用以下函数来实现的该操作:
- 类组件的 constructor,render 以及 shouldComponentUpdate 方法
- 类组件的生命周期方法 getDerivedStateFromProps
- 函数组件体
- 状态更新函数 (即 setState 的第一个参数)
- 函数组件通过使用 useState,useMemo 或者 useReducer
注意:
这仅适用于开发模式。生产模式下生命周期不会被调用两次。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。