I'm new to react.js, just follow the tutorial. Here is my code. At first, i tried to use the class Component 'Greeting' to let it show different words after clicked the button, but i don't know what's wrong, it doesn't rerender the element, and the construtor() method of Greeting only called once. The commented out code functional Component 'Greeting' works well. Not sure what's the difference :(
class GreetingGuest extends React.Component {
render() {
return (
<h3>hello Guest, Click login button !!! </h3>
);
}
}
class GreetingUser extends React.Component {
render() {
return (
<h3>You have logged in, welcome !!!</h3>
);
}
}
class Greeting extends React.Component {
constructor(props) {
super(props);
console.log('Greeting.state.is_logon = ', props.is_logon);
this.state = {is_logon: props.is_logon};
}
render() {
let welcome_msg = null;
if (this.state.is_logon) {
welcome_msg = <GreetingUser />;
}else {
welcome_msg = <GreetingGuest />;
}
return welcome_msg;
}
}
//function Greeting(props) {
// const is_logon = props.is_logon;
// if (is_logon) {
// return <GreetingUser />;
// }
// return <GreetingGuest />;
//}
class LoginComponent extends React.Component {
constructor(props) {
super(props);
this.state = {is_logon: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
is_logon: !prevState.is_logon
}));
}
render() {
let button = null;
let greeting = null;
if (this.state.is_logon) {
button = (
<button onClick={this.handleClick}>Logout</button>
);
greeting = <Greeting is_logon={this.state.is_logon} />
}else {
button = (
<button onClick={this.handleClick}>Login</button>
);
greeting = <Greeting is_logon={this.state.is_logon} />
}
return (
<div>
{greeting}
{button}
</div>
);
}
}
ReactDOM.render(
<LoginComponent />,
document.getElementById('Login')
)
HTML:
<html>
<body>
<div id="Login"></div>
</body>
<html>
The reason the class component doesn't re render, is because you have stored the logged_in
prop in state from the constructor, and the constructor is only called once. Also state can only be modified from within the component.
To fix this you have 2 options;
componentWillReceiveProps
, and update the local state with the new logged_in
prop. componentWillReceiveProps(nextProps) {
if (nextProps.logged_in !== this.state.logged_in) {
this.setState({ logged_in: nextProps.logged_in });
}
}
render() {
let welcome_msg = null;
if (this.props.is_logon) {
welcome_msg = <GreetingUser />;
}else {
welcome_msg = <GreetingGuest />;
}
return welcome_msg;
}
Where I think you should use the latter, since the parent component already maintains state.
Well to be honest the answer which I posted previously was wrong. It was because the way you posted the question telling that everything works fine when function based component is added. Then I created a project using your code and figured out few issues in your code.
Firstly you are maintaining state locally outside redux here. You are passing down the state of the login from the parent LoginComponent
to the child component called Greeting like this.
greeting = <Greeting is_logon={this.state.is_logon} />
This gets passed as a props to the child component which is Greeting
in this case. Remember React uses one way data flow .
Now from that child component you can access the data using this.props
as shown below. You don't need to maintain any local state what so ever there. Do the following changes in your Greeting
component.
constructor(props) {
super(props);
}
Then make sure you access the values from this.props instead of any local state object like this.
render() {
let welcome_msg = null;
if (this.props.is_logon) {
welcome_msg = <GreetingUser />;
}else {
welcome_msg = <GreetingGuest />;
}
return welcome_msg;
}
}
This solved the issue. Happy Coding !
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.