import React from 'react';
import Reactdom from 'react-dom';
class Sub extends React.Component{
constructor(props){
super(props)
this.state = {
count : parseInt(Math.random() * 10)
}
}
subadd(event){
console.log(this.state.count)
console.log(this.props.parent.state.end)
this.setState({ count: parseInt(Math.random() * 10)})
// let temp = parseInt(Math.random() * 10)
// this.state.count = temp
this.props.parent.setState({end: this.state.count}) // count没有改变。此时还没有进行render。
}
componentWillMount(){
console.log('sub', this.state, 111111)
}
componentDidMount(){
console.log('sub', this.state, 222222)
}
componentWillReceiveProps(nexProps){
console.log('sub', this.state, 333333)
}
shouldComponentUpdate(nextProps, nextState){
console.log('sub', this.state, 444444)
return true
}
componentWillUpdate(nextProps, nextState){
console.log('sub', this.state, 555555)
}
componentDidUpdate(prevProps, prevState){
console.log('sub', this.state, 666666)
}
render(){
return (
<div id='t1' onClick={this.subadd.bind(this)} style={{backgroundColor:'#f0f0f0'}}>
click this: {this.state.count.toString()}
</div>
)
}
}
class Root extends React.Component{
constructor(props){
super(props)
this.state = {
p1 : 'www.qq',
p2 : '.xom',
end : ''
}
}
componentWillMount(){
console.log('ROOT', this.state, 111111)
}
componentDidMount(){
console.log('ROOT', this.state, 222222)
}
componentWillReceiveProps(nexProps){
console.log('ROOT', this.state, 333333)
}
shouldComponentUpdate(nextProps, nextState){
console.log('ROOT', this.state, 444444)
return true
}
componentWillUpdate(nextProps, nextState){
console.log('ROOT', this.state, 555555)
}
componentDidUpdate(prevProps, prevState){
console.log('ROOT', this.state, 666666)
}
render(){
return (
<div style={{backgroundColor:'#ff0000'}}>
{this.state.p1.concat(this.state.p2).concat(this.state.end)}
<br />
<Sub parent={this}></Sub>
</div>)
}
}
Reactdom.render(<Root />, document.getElementById('newroot'))
环境:react
实验结果
当点击第二行内容时,触发onclick事件。更改了子组件中state中的值。但未同步修改成功。同时,把父组件的state属性改为子组件中原先的state的值。故,两个值不同步更新。
错误原因:
根据组件的生命周期。属性的更改是在重新渲染时再进行更新。此时并未进行渲染。故值不变
如果需要同步,修改如下:
subadd(event){
console.log(this.state.count)
console.log(this.props.parent.state.end)
// this.setState({ count: parseInt(Math.random() * 10)})
let temp = parseInt(Math.random() * 10)
this.state.count = let
this.props.parent.setState({end: let}) // count没有改变。此时还没有进行render。
}
但是,直接修改属性这种方法不推荐使用。慎用!!!