父组件更新子组件的props
,在子组件接收到新的props
时,需要更新子组件的state
,但是却没有重新渲染。我想在componentWillReceiveProps
方法中更新子组件的state
,但是却没有重新渲染。
官网上有这么一句话:
在该函数中调用
this.setState()
将不会引起第二次渲染。
如果不重新渲染,那么获取到的新数据怎么更新到视图上去?
父组件更新子组件的props
,在子组件接收到新的props
时,需要更新子组件的state
,但是却没有重新渲染。我想在componentWillReceiveProps
方法中更新子组件的state
,但是却没有重新渲染。
官网上有这么一句话:
在该函数中调用
this.setState()
将不会引起第二次渲染。
如果不重新渲染,那么获取到的新数据怎么更新到视图上去?
Use this as an opportunity to react to a prop transition before render() is called by updating the state using this.setState(). The old props can be accessed via this.props. Calling this.setState() within this function will not trigger an additional render.
用此函数可以作为 react 在 prop 传入之后, render() 渲染之前更新 state 的机会。老的 props 可以通过 this.props 获取到。在该函数中调用 this.setState() 将不会引起第二次渲染。
贴上英文文档和中文社区翻译的文档,说的清楚:在render之前可以更新state,不会引起第二次渲染并不是说不渲染.碰到这种情况,自己写个简单demo试试不就知道了?在附上测试代码
class Child extends Component {
constructor(props) {
super();
this.state = {
text: props.text
}
}
componentWillReceiveProps(nextProps) {
this.setState({
text: nextProps.text
});
}
render() {
return <p>{this.state.text}</p>
}
}
class Parent extends Component {
state = {
name: 'xxx'
}
render() {
return (
<div>
<Child text={this.state.name}/>
<button onClick={() => this.setState({name: 'zzz'})}>change</button>
</div>
)
}
}
先说下你的 prop 的格式,和在 componentWillReceiveProps 里怎么做的吧,另,有没有写 shouldComponentUpdate。
setState 不会引发的是 第二次渲染,也就是说进入 componentWillReceiveProps 就已经是第一次渲染了,如果在其他生命周期里调用,还会引发第二次渲染,但是 componentWillReceiveProps 里不会
这里说的不会造成第二次的渲染,并不是说这里的setState
不会生效。在这个方法里调用setState
会在组件更新完成之后在render
方法执行之前更新状态,将两次的渲染合并在一起。可以在componentWillReceiveProps
执行setState
,但是如果你想在这个方法里获取this.state
得到的将会是上一次的状态。
永远不要在 constructor 里使用props初始化state值,不然就会导致这个问题;要么直接用props渲染,要么使用新的生命周期函数
class Child extends Component {
state = { text: '' };
//getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.
static getDerivedStateFromProps(props) {
return {
text: props.text
};
}
render() {
return <p>{this.state.text}</p>
}
}
class Parent extends Component {
state = {
name: 'xxx'
}
render() {
return (
<div>
<Child text={this.state.name}/>
<button onClick={() => this.setState({name: 'zzz'})}>change</button>
</div>
)
}
}
5 回答8.2k 阅读
2 回答10.3k 阅读✓ 已解决
2 回答10.5k 阅读✓ 已解决
3 回答4.7k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答1.7k 阅读
3 回答2.1k 阅读✓ 已解决
子组件显示父组件穿过来的
props
有两种方式:1、直接使用
这种方式,父组件改变
props
后,子组件重新渲染,由于直接使用的props
,所以我们不需要做什么就可以正常显示最新的props
2、转换成自己的
state
这种方式,由于我们使用的是
state
,所以每当父组件每次重新传递props
时,我们需要重新处理下,将props
转换成自己的state
,这里就用到了componentWillReceiveProps
。关于你提到的
不会二次渲染
是这样的:每次子组件接收到新的props
,都会重新渲染一次,除非你做了处理来阻止(比如使用:shouldComponentUpdate
),但是你可以在这次渲染前,根据新的props
更新state
,更新state
也会触发一次重新渲染,但react
不会这么傻,所以只会渲染一次,这对应用的性能是有利的。谢邀回答!