目录

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({
    obj
});

解决办法: 克隆

// 正确方式
const obj = Object.JSON(Object.stringify(this.state.obj));

obj.forEach((e) => {
        xxxxx //省略的代码是改变了对象的值
});

this.setState({
    obj
});

原因: 对象数组是引用方式 ,对于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节点, 再删除;如果你有其他好办法好想法可以留言一起学习讨论!

本人开发的微信小程序(已上线):
有兴趣的可以看看, 可一键三连点点关注谢谢大家~
1、小绿抑郁测试助手(微信小程序):一个完全免费无广告的抑郁症自测小程序, 收集了来自全球权威的问卷免费提供给大家使用.有新颖的的分数记录和海报分享, 可看可学!

小绿抑郁助手
小绿抑郁测试助手
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐