reactjs 父组件如何触发子组件的state?

先看代码

import React from 'react';


//子对象只是实现一个累累加的计算
class Son extens React.Component{
    constructor(props){
        super(props)
        
        this.state = {'A':props.A};
    }
    
    handleAdd(){
        this.setState({'A': this.state.A++};
    }
    
    render(){
        return(
            <div>
                <button onClick={this.handleAdd} > 累加</button>
                <div>{this.state.A} </div>
            </div>
        )
    }
}
//父对象
class Dad extends React.Component{
    
    constructor(props){
        super(props)
        
        this.state = {'SA': 1};
    }
    
    handleChangeA(){
        //目的是将Son A的属性可以动态修改 
        this.setState({SA:math.random()});
    }
        
    render(){
        <div>
            <Son A={this.state.SA} />
            <button onClick={this.handleChange}>修改基础值</button>
        </div>
    }
}

现在的问题是:

初始化的时候Son很容易接受Dad的值. 但是当 Dad赋值给Son A的值动态变化后,Son该如何将props.A传给state.A?

其实问题的根本子组件和父都会修改 子组件本身的状态问题.


感谢回复.

阅读 33.1k
8 个回答
import React from 'react';

//子对象只是实现一个累累加的计算
class Son extends React.Component{
    static defaultProps = {
        A: 0,
        onChange: new Function
    };
    static PropTypes = {
        A: React.PropTypes.number
        onChange: React.PropTypes.func
    };
    
    componentWillReceiveProps(nextProps) {
        this.setState({A: nextProps.A});
    }
    
    handleAdd() {
        let A = this.state.A++;
        this.setState({A}, ()=> this.props.onChange(A));
    }
    
    render(){
        return(
            <div>
                <button onClick={this.handleAdd} > 累加</button>
                <div>{this.state.A} </div>
            </div>
        )
    }
}

//父对象
class Dad extends React.Component{
    state = {
        SA: 1
    };
    
    handleChangeA(){
        //目的是将Son A的属性可以动态修改 
        this.setState({SA: Math.random()});
    }
        
    render(){
        <div>
            <Son A={this.state.SA} onChange={val => this.setState({SA: val})}/>
            <button onClick={this.handleChange}>修改基础值</button>
        </div>
    }
    
}

你去好好看一下React组件生命周期这一部分。你可以在子组件添加一个componentWillRecieveProps周期,在里面获取到即将接收的props。如下:

componentWillReceiveProps(nextProps) {
   this.setState({
     A: nextProps.A
   });
}

如果只是简单的传值,并不需要这么麻烦。
题主说的问题我之前也是踩过坑的。出现这个问题的原因是我们多做了一步,就是把props
赋值给state然后再放到组件中。

为什么说多做了一步?

在react中,子组件是会自动响应父组件传的props的,而之所以值改变了子组件不刷新,问题就出在你一开始不最开始的props赋值给了state,而后面你更新props时并没有做相同的操作。

最好的做法就是,直接在组件中使用props,而不是state。这样父组件传的值一变子组件马上就变了。

另外如果你传的不是简单的值,需要覆写刷新那个生命周期函数进行修改。楼上已经提到了这里不再赘述

先理解理论。
1)react官方说的很清楚:触发状态变化,只有两个原因:属性变化,和自身调用setState方法;又规定自己不能修改自己的属性。
2)从1)得出:父的状态,为子的属性就能引起子的状态变化。
3)按照js的基本理论一切都是对象。那么就是说,你在子组件拿到父的引用引用,就能执行父组件的一切方法,反之也成立。 怎么拿? 在父组件把this当做子组件某属性传给子,反之也行,但是反之没什么意义,一是复杂,二是违背了react的设计哲学

首先说一下

1.你定义子组件的时候把方法声明为handle,然而在onclick事件调用的时候写成handleAdd了

2.在父组件的setState里的json对象没有把SA放到引号

这些问题处理了之后

点击子组建的按钮不可能改变父组件的状态,因为在react数据是单向的,你可以把父组件的方法用props传递给子组建再在子组建调用此方法

点击父组件的按钮可能会改变子组件的状态,这点我没有把握,你试试就知道了

所有状态声明到dad,通过prop传到son去,修改dad状态的方法写在dad里,通过prop传进去

新手上路,请多包涵
    class ChangeFun extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                city: this.props.cityId
            }
        }
        render() {
            return (
                <div>
                    <div className="myTest">
                        hello: 我是changeFun2 { this.state.city }
                    </div>
                </div>
            )
        }
    }
export default class Test extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            city: 11
        }
    }

    setCity(cityName) {
        return this.setState({city: cityName})
    }
    render() {
        return (
            <div>
                <div className="myClick">
                    <span className="clickEle"
                          onClick={()=>{
                    this.setCity("苏州",()=>{});
                    }}>点我变苏州</span>
                    <span className="clickEle" onClick={()=>{
                     this.setCity("杭州",()=>{});
                    }}>点我变杭州</span>
                    <span className="clickEle" onClick={()=>{
                    this.setCity("上海",()=>{});
                    }}>点我变上海</span>
                </div>
                <div>{ this.state.city }</div>
                <div>
                    <ChangeFun cityId={ this.state.city }/>
                </div>
            </div>


        )
    }
}

这里为什么父级的点击事件并没有影响子级?

父组件传递给子组件的props发生改变,引发子组件的render,并没有执行子组件的constructor函数,子组件没有被卸载自然不会重新加载,只会重新render,而如果父组件的props传递给子组件的state,那么子组件的state只会在第一次加载的时候被赋值,后续的父组件props变化并不会被赋值到子组件的state上,还是要理解组件的声明周期函数,以及各个函数在什么时候会被调用。

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