Reputation: 1009
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
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
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