1. 组件 render 渲染了一个对象, 当 state 已确定更新但视图未更新
2. 组件 render 渲染了一个列表, 当 state 改变视图更新异常
3. A 和 B 子组件共用一个父组件 state, 此时点击子组件 A 按钮更新了父组件 state, 但是子组件 B 视图不更新
4. 父子组件同时初始化, 子组件接收的值来自父组件异步获取的数据
5. 调用方法中 state 更新了, 但实时拿到的值还是旧的
6. 在 redux 中修改 state 页面未更新
7. 当列表循环渲染之后, 改变当前 item 页面数据不变
1. 组件 render 渲染了一个对象, 当 state 已确定更新但视图未更新
// 错误方式
const obj = this.state.obj;
obj.forEach((e) => {
xxxxx //省略的代码是改变了对象的值
this.setState({
解决办法: 浅拷贝方式获取对象并修改再赋值。
// 正确方式
const obj = [...this.state.obj];
obj.forEach((e) => {
xxxxx //省略的代码是改变了对象的值
this.setState({
原因: 对象数组是引用方式 , 对于 react 来说它的值都是地址 (涉及到 tree diff),因为没有被重新赋值 (地址没有改变),所以 react 会认为仍然是之前的元素 (element),则不更新视图。
react 更新 state 后视图没有变化
react 学习笔记 - 解决 react 修改 state 对象,页面不刷新问题
2. 组件 render 渲染了一个列表, 当 state 改变视图更新异常
{this.state.string.split('').map((item,index)=><p key={index}>item</p>)}
//其中this.state.string = '1' 且每秒钟 +1 ,此时页面视图未发生变化
解决办法: key={index} 改成 key={item+index}。
原因: key 是唯一的. 而 1 和 10 在 split 后是 [1] 和[1,0], 他们都共有 1, 这时候就会导致组件状态问题。
react 列表渲染时为什么尽量不要把索引设置为 key 值
3. A 和 B 子组件共用一个父组件 state, 此时点击子组件 A 按钮更新了父组件 state, 但是子组件 B 视图不更新
解决办法: 同上 (2)。
原因: 同一个页面调用同的组件 (出现问题的组件) 的 key 都用了 index, 也会导致组件状态问题。
4. 父子组件同时初始化, 子组件接收的值来自父组件异步获取的数据
初始化 state.value=' ',
componentDidMount 时, 父组件异步获取数据赋给 state.value,
而子组件一同初始化 componentDidMount 中拿到的 state.value 还是空的。
解决办法:
// render中判断state.value不等于空,再加载子组件即可
render() {
return (
{ this.state.value? <subComp value={this.state.value}>我是子组件</subComp> : '' }
原因: 因为子组件已经 componentDidMount 渲染完成了, 父组件异步获取数据就没办法拿到。
拓展: 貌似 componentWillReceiveProps 是符合需求的, 但是我用过几次有出现问题搞不定需求就没再用了。
5. 调用方法中 state 更新了, 但实时拿到的值还是旧的
//默认string等于''
this.setState({
string: '123'
console.log(this.state.string)//''
解决办法:
this.setState({
string: '123'
},()=>{
//setState后的回调
console.log(this.state.string)//'123'
原因: react 还没更新 state, 打印就执行完毕了。
6. 在 redux 中修改 state 页面未更新
**解决办法: ** 请检查你的 state 是不是直接改变原 state 的, 记住不要直接修改 state。
原因: reducer 中 state 是引用, 在 reducer 中改变 state 是错误的, 虽然 store 里面的 state 是改变了, 但是 react - redux 会认为 dispatch 前后的 state 没有改变,就不会重新渲染页面。
react State 改变,页面却没有改变
state 更新了,组件却没有更新
7. 当列表循环渲染之后, 触发事件改变事件对应的值, 视图不更新
还有一种情况是如下, 直接改变源数据发现是没有变化的, 只有触发视图重排才会有效果
obj.map(item=>{
<span onClick={()=>{item.name=1}}>{item.name}<span>
对象内的数据没有做监听
解决办法:
想办法触发视图重排, 重排方法很多; 我暂时能想到的是添加一个 node 节点, 再删除; 如果你有其他好办法好想法可以留言一起学习讨论!
作者:拒绝996从我做起
链接:https://juejin.cn/post/6911627178970972174
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。