react中父层变量传入子层,改变父层变量,子层变量没变

// Father.js
class Father extends Component {
  constructor(props){
    super(props);
    this.state = {
      reset: 'unreset',
      father: {
        name:'father'
      }
    };
    this.resetData = this.resetData.bind(this);
  }
  resetData () {
    this.setState({
      father: {
        name:'father 2'
      }
    });
  }
  render() {
    return (
      <div className="App">
        <Child father={this.state.father} resetData={this.resetData}/>
      </div>
    );
  }
}
export default Father;
// Child.js
class Child extends Component {
  constructor(props){
    super(props);
    const {father} = this.props;
    this.state = {
      isChange: 'unChange',
      father: father,
    };
    this.change = this.change.bind(this);
  }
  change () {
    this.setState({
      isChange: 'change',
    });
    setTimeout(this.props.resetData,2000);
  }
  render() {
    return (
      <div className="App" onClick={this.change}>
        {this.state.isChange}
        <br/>
        {this.props.father.name}
        <br/>
        {this.state.father.name}
      </div>
    );
  }
}
export default Child;

为什么点击之后只有一个改变?
点击前
图片描述
点击后
图片描述

阅读 4.7k
5 个回答

1.两个father变量都是引用类型,但是父组件的resetData直接改变了father的地址,子组件引用的仍然是旧的father

2.你只在构造函数内把props.father的值赋给了state.father,后面随着props.father的改变,state.father并不会主动响应,原因见上一点

3.解决方法有两种:
1)全都用props.father
2)添加componentWillReceiveProps函数:

componentWillReceiveProps = (nextProps) => {
  this.setState({
    father: nextProps.father
  })
}

在state发生变化时,重新渲染组件,是不会再走super()方法的,会重新调用render()方法,因此,子组件this.state.father.name,你在super()声明而已,并没有发生变化。

我记得在constructor中通过this.props是取不到值的

不好意思~ 我搞错了了~

var a,b;
a='father';
b=a;
console.log(a,b);
a='father 2';
console.log(a,b);
你考虑考虑上面这段代码结果是什么

1.你在子组件里把父组件传过来的props用state缓存起来了,由于父组件属性更新的时候子组件不会重新渲染,不会再走构造函数,所以子组件的state不会和父组件的props保持同步,这个时候你需要在componentWillReceiveProps(nextProps) 里去处理
2.也可以不缓存到state里,直接在render函数里用父组件传过来的props

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题