Reputation: 102327
import React, { Component } from "react";
export interface MyComponentProps {
show: boolean;
}
export interface MyComponentState {
show: boolean;
}
export default class App extends Component<MyComponentProps, MyComponentState> {
static defaultProps = {
show: true
};
static getDerivedStateFromProps(props: MyComponentProps) {
console.log("getDerivedStateFromProps: ", props);
if ("show" in props) {
return { show: props.show };
}
return null;
}
constructor(props: MyComponentProps) {
super(props);
this.state = {
show: props.show
};
}
onClick() {
this.setState({ show: false });
}
render() {
const { show } = this.state;
return (
<div>
{show ? "teresa teng" : ""}
<button type="button" onClick={() => this.onClick()}>
toggle
</button>
</div>
);
}
}
getDerivedStateFromProps()
static method will be executed after setState()
. So I click the button to try to change the value of state.show
to false
, but the getDerivedStateFromProps()
method will change state.show
to true
. So the text will always be visible.
getDerivedStateFromProps
intends to use the props passed in by the parent component to update the state.
How can I solve this? Playground codesandbox.
Upvotes: 0
Views: 39
Reputation: 2609
getDerviedStateFromProps
is bound to run after every prop and state change. This was not an actual design but this change in functionality was introduced in React version 16.4 (if I remember correctly).
Now, if you want to update the local show i.e. your state on the basis of your props, you can:
Pass a callback which updates show
for you in the parent component and then use the new prop value.(As mentioned by @jonrsharpe in the comments).
You can also make use of a key
prop which tells your component to completely unmount and mount itself in case of a key change. This will lead to the state getting reset based on the value of the props.
For ex,
<App show={this.state.show}
key={this.state.show}/>
Example CodeSandBox
Upvotes: 1