从 child 个组件更改 parent 个组件状态

Change parent component state from child component

我知道这个标题的问题已经被问过几次了,但问题是我找不到合适的答案。因此,我是 reactJS 的新手,正在尝试创建登录注销表单。

我想要做的是通过事件处理程序从 child 组件传递或更改 parent 组件的状态(当用户单击注销按钮时).下面是两个组件:

第一个:

class Home extends React.Component {
    constructor(props){
        super(props);
        this.state = {login : false};
    }

    login(){
       // this method updates the login.state : true
    }


    render() {
        return (
            <div>
                {this.state.login ? (<ChatBox userNick="fad" />) : (<LoginScreen onSubmit={this.login} />) }
            </div>
        );
    }
}

第二个:

class ChatBox extends React.Component{
    logout(){
        // Expecting or trying to update parent.state.login : false
        // via this method as well
    }

    render() {
        return (
            <div className="chat-box">
                <button onClick={this.logout} > Logout </button>
                <h3>Hi, {this.props.userNick} </h3>
            </div>
        );
    }
}

我已经简化了这些组件来点。

这是怎么回事? Home 组件是主要的 parent 组件。最初 state.loginfalse,在这种情况下 LoginScreen 组件出现。现在,当用户通过 LoginScreen 组件登录时 state.login 更新为 true,是时候显示 ChatBox 组件了。

现在您可以看到 ChatBox 组件包含一个按钮,该按钮调用方法 logout 来注销用户。 我想要的 是再次更新 Home 组件中的 state.loginfalse 当用户点击 注销按钮.

我不知道怎么做,如果你能帮助我,我将不胜感激。

提前致谢。

以与登录相同的方式执行此操作,将函数作为 prop 传递并在注销时调用它,请参阅下面的更新。

const LoginScreen = () => (<div>Login Screen</div>);

class Home extends React.Component {
    constructor(props){
        super(props);
        this.state = {login : true};
        this.logout = this.logout.bind(this);
    }

    login(){
       // this method updates the login.state : true
    }

    logout() {
       // this method updates the login.state : false
       this.setState({ login: false });
    }

    render() {
        return (
            <div>
                {this.state.login ? (<ChatBox userNick="fad" onLogout={this.logout} />) : (<LoginScreen onSubmit={this.login} />) }
            </div>
        );
    }
}

class ChatBox extends React.Component{
    constructor(props) {
        super(props)
        // This makes sure `this` keeps pointing on this instance when logout is called from the outside.
        this.logout = this.logout.bind(this);
    }

    logout(){
        // Call the onLogout property.
        this.props.onLogout();
    }

    render() {
        return (
            <div className="chat-box">
                <button onClick={this.logout} > Logout </button>
                <h3>Hi, {this.props.userNick} </h3>
            </div>
        );
    }
}

ReactDOM.render(<Home />, document.querySelector('#main'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="main"></div>

您可以将事件从 Parent 组件传递到处理状态更改的 Child 组件,如下所示:

class App extends React.Component {

  constructor() {
    super();
    this.state = { isLoggedIn: false };
  }

  _handleLogin() {
    this.setState({ isLoggedIn: true });
  }

  _handleLogout() {
    this.setState({ isLoggedIn: false });
  }

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

    return (
        <div>
       {
            isLoggedIn ?
            <ChatBox logoutEvent={this._handleLogout.bind(this)} />
          :
          <Login loginEvent={this._handleLogin.bind(this)} />
       }
        </div>
    );
  }
}

const Login = ({ loginEvent }) => (
    <button type="button" onClick={loginEvent}>Login</button>
);

const ChatBox = ({ logoutEvent }) => (
    <div>  
    <h1>This is the Chat Box!</h1>
    <button type="button" onClick={logoutEvent}>Logout</button>
  </div>
);

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

这是fiddle