繁体   English   中英

在父组件中单击按钮时,如何控制该子组件的状态?

[英]How do I control the state of this child component upon a button click in its parent?

我正在努力找出在我正在构建的站点上构建两个 React 组件的最佳方法。

我有一个“书评”组件,当点击评论时,它应该显示相应的模式(通过将“is-active”类添加到<div className="modal" /> )。 为简单起见,假设在此页面上有一个带有onClick的按钮,可打开单个模式。 这个模态的背景占据了整个屏幕,所以当模态的背景被点击时,模态应该关闭。

关闭模态很容易——我只是将_closeModal函数绑定到模态背景。 但是如何从书评中打开模态?

模态.js

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

    this.state = {
      modalOpen: false,
    };
  }

  render() {
    return (
      <div className={`modal ${this.state.modalOpen ? "is-active" : ""}`}>
        <div className="modal-background" onClick={this._closeModal}>
      ...
        </div>
      </div>
    )
  }

  _closeModal = () => {
    this.setState({
      modalOpen: false,
    })
  }
}

书评.js

class BookReview extends React.Component {
  render() {
    return (
      <div>
        <Modal />
        <button onClick={/* open the modal */}>Open Modal</button>
      ...
      </div>
    )
  }
}

我觉得我应该从它自己的组件中控制模态状态,而不是书评。 书评已经有一个包含大量信息的状态对象,所以我的直觉是跟踪所有模态状态也会变得非常混乱。

在其他线程中,人们说您不应该尝试从父组件控制子状态。 主要问题是我需要_closeModal位于子组件内(因为模态背景占据整个屏幕)和_openModal位于父组件内(因为在调用此函数之前模态甚至不可见)。 任何建议表示赞赏!

您应该有stateBookReview组件中打开模态,并将其作为props传递给子组件

class BookReview extends React.Component {
  state={modalOpen: false}

  _openModal = () => {
     this.setState({modalOpen:true})
  }
  render() {
    return (
      <div>
        <Modal isOpen={this.state.modalOpen}/>
        <button onClick={this._openModal}>Open Modal</button>
      ...
      </div>
    )
  }
}

在子组件,您应该使用props从父开放模式,并componentDidUpdate后续props的变化。

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

    this.state = {
      modalOpen: props.isOpen,
    };
  }

  componentDidUpdate(prevProps) {   //This will take care of props change from parent
   if (prevProps.isOpen !== this.props.isOpen) {
     this.setState({modalOpen:this.props.isOpen},()=>console.log(this.state.modalOpen))
   }
  }

  render() {
    return (
      <div className={`modal ${this.state.modalOpen ? "is-active" : ""}`}>
        <div className="modal-background" onClick={this._closeModal}>
      ...
        </div>
      </div>
    )
  }

  _closeModal = () => {
    this.setState({
      modalOpen: false,
    })
  }
}

在 Modal 组件中添加打开 modal 的方法

openModal(){
    // set modal open
}

在书评组件中:

<modal ref="modal" />
<button onClick={() => this.refs.modal.openModal()}>Click</button>

我建议在父组件中保留打开和关闭模态的逻辑。 所以 BookReview 组件可以完全控制它。 Modal 只知道如果一个 prop 设置为 true 它应该显示 Modal。 这是修改后的解决方案:

import React from 'react';

class Modal extends React.PureComponent {
    render() {
        return (
            <div className={`modal ${this.props.isOpen ? "is-active" : ""}`}>
                <div className="modal-background" onClick={this.props.closeModal}>
                    this is a modal
                </div>
            </div>
        )
    }
}

class BookReview extends React.Component {

    constructor(props){
        super(props);
        this.state = {
            isOpen:false
        };
        this.openModal = this.openModal.bind(this);
        this.closeModal = this.closeModal.bind(this);
    }

    openModal(){
        this.setState({isOpen: true});
        console.log('modal opened');

    }

    closeModal(){
        this.setState({isOpen:false});
        console.log('modal closed');
    }

    render() {
        return (
            <div>
                <Modal isOpen={this.state.isOpen} closeModal={this.closeModal}/>
                <button onClick={this.openModal}>Open Modal</button>
            </div>
        )
    }
}

export default BookReview;

我还假设会有一个 BookReview 的父组件渲染列表。 因此,您可以在 BookReview 中传递 bookId 属性,并使用 BookReview 父级来控制正在显示哪个 BookReview 的模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM