美文网首页
React爬坑之路——子组件更新父组件state值

React爬坑之路——子组件更新父组件state值

作者: DeepBig胜 | 来源:发表于2018-09-29 10:21 被阅读0次

        本文代码基于React,Antd的Radio以及Radio.Group,模拟的需求是:
        当有三个RadioGroup的时候,第一个RadioGroup的选择值将改变后面两个RadioGroup的状态,当第一个RadioGroup选择为1时,其他两个RadioGroup将不能使用(通过disabled来控制)。我们可以通过使用回调函数来完成这一需求:

    1. 首先是父组件有一个相对于三个子组件的全局的值isEnabled,这个值表示第二、第三个子组件是否可以使用,因此需要将isEnabled传给这两个子组件;
    2. 父组件提供一个changeEnabled方法接受一个value参数,根据这个参数,来更改isEnabled值(value为1,则为false,否则为true)。这个方法就是给子组件调用的,回调函数,将由父组件传给第一个子组件;
    3. 第一个子组件通过调用与RadioGroup的onClick绑定的方法handleChange,来更新它本身的value值,同时回调方法changeEnabled,并传入更新的value值;
    4. 父组件的changeEnabled被调用后,根据value值,及时更新自己的isEnabled值,以更改第二、第三个子组件状态。
    5. 在子组件中请注意render()方法中的这一行代码:const {isEnabled} = this.props,而不是将isEnabled放到子组件的constructor(props)。
    总结:核心思想,即父组件拥有某个状态变量,也拥有更新这个状态变量的函数,父组件把这个函数传递给子组件,然后通过子组件的调用来更新这个状态变量。

        本人是刚刚入门React不久的新手,语言组织也可能有些混乱。如有问题,请大神多多指教。

    完整代码如下:
    其中,

    1. Radios是存放一个RadioGroup的子组件,RadioGroups是父组件,存放三个Radios。
    2. 子组件中render()方法的这一行代码 const {isEnabled} = this.props; 尤其重要,它能够及时接收父组件的isEnabled值的变化而更新自己的RadioGroup状态。但此处笔者有个问题是,为何不能将isEnabled放到constructor里面,作为子组件本身的state值,希望有高手能够指点一下。
    //RadioGroups
    import React, {Component} from 'react';
    import {Radio} from 'antd';
    const RadioGroup = Radio.Group;
    
    class Radios extends Component{
        constructor(props){
            super(props);
            this.handleChange = this.handleChange.bind(this);
            this.state = {
                value : 1,      //RadioGroup初始化值为1,表示选择第一个选项
            };
        }
    
        handleChange(e){
            this.setState({
                value : e.target.value,
            });
            console.log('value: ' + e.target.value + ' ' + this.props.changeEnabled);
    
            // 子组件更新RadioGroup值的同时,回调父组件的changeEnabled方法以更新其isEnabled值,
            // 如果方法为undefined,说明不是第一个RadioGroup
            if(this.props.changeEnabled !== undefined){
                this.props.changeEnabled(e.target.value);
                console.log('changed');
            }
        }
    
        render(){
            //接收父组件传进来的isEnabled值,以更新子组件的状态(对应下面RadioGroup的disabled状态)
            const {isEnabled} = this.props;    
            return (
                <div>
                    {/*disabled值根据父组件的isEnabled改变而改变,如果为undefined,说明是第一个Radio组,不会随着父组件的isEnabled改变。*/}
                <RadioGroup disabled={!isEnabled} value={this.state.value} onChange={this.handleChange}>
                    <Radio value={1}>1</Radio>
                    <Radio value={2}>2</Radio>
                    <Radio value={3}>3</Radio>
                </RadioGroup>
                </div>
            );
        }
    }
    
    class RadioGroups extends Component{
        constructor(props){
            super(props);
            this.changeEnabled = this.changeEnabled.bind(this);
            this.state = {
                isEnabled: false,
            };
        }
    
        //父组件中的回调函数(给子组件调用)
        changeEnabled(value){
            this.setState({
               isEnabled : value !== 1
            });
            console.log(this.state.isEnabled)
        }
    
        render(){
            return (
                <div>
                    {/*只将回调方法传给第一个组件,这样其他两个组件的值将不影响父组件的state*/}
                    {/*而isEnabled第一个组件保持为true,以保证其一直可以使用*/}
                    <Radios isEnabled={true} changeEnabled={this.changeEnabled}/>
                    <Radios isEnabled={this.state.isEnabled}/>
                    <Radios isEnabled={this.state.isEnabled}/>
                </div>
            );
        }
    }
    
    export default RadioGroups;
    
    本文须知的坑:

        1. 一定要学习好React的生命周期,其中每个组件的constructor只会调用一次,因此必须将要更新的值放到render方法里面而不是constructor里面,如Radios组件中render()方法里的const {isEnabled} = this.props;

    相关文章

      网友评论

          本文标题:React爬坑之路——子组件更新父组件state值

          本文链接:https://www.haomeiwen.com/subject/sdrvoftx.html