如何将子状态的真假传递给父反应

时间:2019-05-29 14:13:52

标签: reactjs setstate

我有两个组成部分,一个是父母(小部件),另一个是儿子(Telefono)。 “ Telefono”组件的状态为notInCall,通过它我可以绘制或不绘制代码的特定部分。 另一方面,我具有showComponent()函数,该函数位于父对象中,用于显示或不显示子组件(Telefono)和其他两个组件。 我需要从父级中恢复,在the showComponent()函数中,notInCall的当前状态(正确或错误),但我不知道该怎么做。

编辑:我认为我的解释不够好。在孩子中,我使用条件this.state.notInCall来显示或不显示部分代码。我需要将truefalse响应传递给父级。如果是{this.state.notInCall ? (some code) : (another code)}。如果孩子上的this.state.notInCalltrue,则做一件事,如果孩子是false,则做另一件事

这是我的父组件(小部件)

class Widgets extends Component {   
    constructor(props) {
        super(props);
        this.state = {
            componente: 1,
            //notInCall: false,
        };
        this.showComponent = this.showComponent.bind(this);
    }

    showComponent(componentName) {
        /*this.setState({
            notInCall: false,
        });*/
        if(this.state.notInCall === false){
            this.setState({
                componente: Telefono,
                addActive: Telefono,
            });
            alert(this.state.notInCall + ' running? Componente:' + componentName);
            console.log(this.state.notInCall);
        }else{
            alert('verdad');
            this.setState({
                componente: componentName,
                addActive: componentName,
            });            
        }
        console.log(this.state.notInCall);
    }

    renderComponent(){
        switch(this.state.componente) {
            case "ChatInterno":
                return <ChatInterno />
            case "HistorialLlamadas":
                return <HistorialLlamadas />
            case "Telefono":
            default:
                return <Telefono showComponent={this.showComponent}/>
        }
    }

    render(){
        return (
            <div id="bq-comunicacion">
                <nav>
                    <ul>
                        <li><button onClick={() => this.showComponent('Telefono')} id="mn-telefono" className={this.state.addActive === 'Telefono' ? 'active' : ''}><Icon icon="telefono" className='ico-telefono'/></button></li>
                        <li><button onClick={() => this.showComponent('ChatInterno')} id="mn-chat" className={this.state.addActive === 'ChatInterno' ? 'active' : ''}><Icon icon="chat-interno" className='ico-chat-interno'/></button></li>
                        <li><button onClick={() => this.showComponent('HistorialLlamadas')} id="mn-llamadas" className={this.state.addActive === 'HistorialLlamadas' ? 'active' : ''}><Icon icon="historial-llamadas" className='ico-historial-llamadas'/></button></li>
                    </ul>
                </nav>
                <div className="content">
                    { this.renderComponent() }
                </div>
            </div>
        );
    }
}

这是我的子组件(Telefono)

class Telefono extends Component {
    constructor(props) {
        super(props);

        this.inputTelephone = React.createRef();

        ["update", "reset", "deleteClickNumber", "closeAlert", "handleKeyPress",].forEach((method) => {
            this[method] = this[method].bind(this);
        });

        this.state = this.initialState = {
            notInCall: true,
            isRunning: false,
        };
    }

    phoneCall(e){
        e.preventDefault();
        this.props.showComponent(this.state.notInCall);

        if(this.state.inputContent.length < 2){
            this.setState({
                warningEmptyPhone: true,
            });

            this.change = setTimeout(() => {
                this.setState({
                    warningEmptyPhone: false
                })
            }, 5000)
        }else if(this.state.inputContent.length >= 2 ){
            this.setState({
                notInCall: !this.state.notInCall,
                isRunning: !this.state.isRunning,
                componente: 'Telefono',
            }, 
                () => {
                    this.state.isRunning ? this.startTimer() : clearInterval(this.timer);
                    //console.log(this.componente);
                });
        }
    }

    render(){
        return(
            <div className="pad sb-content">
                {this.state.notInCall
                    ? (
                        <>
                        <div className="dial-pad">
                            <div className="digits">
                                <Numbers numbers={this.state.numbers}
                                />
                            </div>
                        </div>
                        <div className="btn-call call" onClick={this.phoneCall.bind(this)}>
                            <Icon icon="telefono" className='ico-telefono'/>
                            <span>LLAMAR</span>
                        </div>
                        </>
                    )
                    : (
                        <div className="call-pad">
                            <div id="ca-number" className="ca-number">{this.state.inputContent}</div>
                            <TimeElapsed id="timer" timeElapsed={timeElapsed}/>
                        </div>    

                    )}
            </div>
        );
    }
}

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您可以在父级中创建一个句柄,例如:


handleNotInCall (notInCall) {
  // handle here
}

并将此句柄传递给孩子:

<Telefono handleNotInCall={this.handleNotInCall} />

在孩子中,您这样称呼:


this.props.handleNotInCall(<param here>)

更新

关于父母: 关于父母:

  • notInCall置于状态
  • notInCall创建一个句柄
  • 传递子句柄和状态
// state
this.state = {
  componente: 1,
  notInCall: false,
};
// create a handle
handleNotInCall (notInCall) {
  this.setState({notInCall});
}
// pass both for child
<Telefono handleNotInCall={this.handleNotInCall} notInCall={this.state.notInCall}/>

在儿童中,您在哪里:

this.setState({
  notInCall: !this.state.notInCall,
  isRunning: !this.state.isRunning,
  componente: 'Telefono',
})
// change for
this.props.handleNotInCall(!this.props.notInCall)
this.setState({
  isRunning: !this.state.isRunning,
  componente: 'Telefono',
})

// where you use for compare 
this.state.notInCall ? 
// change for:
this.props.notInCall ?

答案 1 :(得分:0)

如果我正确理解了您的问题,则Marcello Silva的答案是正确的。

说你有这个:

class Parent extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            childAvailable: true,
        };
    }

    handleAvailability = status => {
        this.setState({ childAvailable: status });
    }

    render() {
        const { childAvailable } = this.state;

        if (!childAvailable) {
            return (...); // display whatever you want if children not available
        } else {
            return (
                <div>
                    {children.map(child => {
                        <Children
                            child={child}
                            statusHandler={this.handleAvailability}
                        />
                    }
                </div>
            );
        }
    }
}

class Children extends React.Component {
    constructor(props) {
         super(props);

         this.state = {
             available: true,
         };
    }

    handleClick = e => {
        const status = !this.state.available;
        this.setState(prevState => { available: !prevState.available });

        // if you call the handler provided by the parent here, with the value
        // of status, it will change the state in the parent, hence
        // trigger a re render conditionned by your value
        this.props.statusHandler(status);
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>Click me to change status</button>
            </div>
        );
    }
}

执行此操作将调用您作为prop传递给父母中的孩子的函数。此函数设置您的状态,因此一旦设置了状态,就会触发重新渲染,因此考虑到childAvailable的新值,您将可以渲染任何内容。

编辑:看到对上述答案的评论后,我想补充一点,您当然可以根据您在handleClick上的条件来调用this.state.notInCall方法。 / p>