Syed Aqeel
Syed Aqeel

Reputation: 1009

Change parent component state from child component

I know that the question with this title has already been asked few times before but the problem is that I couldn't get an appropriate answer. So as I am new to reactJS and trying to create login logout form.

What I want to do is to pass or change a state of parent component from a child component through an event handler(When a user clicks on logout button). Below are the two Components:

First One:

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>
        );
    }
}

And Second:

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>
        );
    }
}

I have simplified these component to come on point.

What's going here? Home Component is the main parent component. Initially the state.login is false and in this situation LoginScreen Components shows up. Now, when user login through LoginScreen Component state.login updates to true, it's time to show for ChatBox Component.

Now you can see that ChatBox Component contains a button which calls a method logout to logout user. What I want is to update once again the state.login to false in Home Component When user click on the Logout Button.

I don't know how to do it, It will be appreciate if you help me.

Thanks in advance.

Upvotes: 0

Views: 1217

Answers (2)

Ganhammar
Ganhammar

Reputation: 1951

Do it in the same way as you are doing for Login, pass a function as a prop and call it on logout, see updates below.

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>

Upvotes: 2

ickyrr
ickyrr

Reputation: 2113

You can pass an event from the Parent component to the Child component that handles the change of the state, like so:

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')
);

Here's the fiddle

Upvotes: 1

Related Questions