I'm trying to move from componentWillReceiveProps to getDerivedStateFromProps and in some cases, I was successful but when the case is append the props to the existing state, the things start to not behaving the same way. When a make a update to the component's state, the state changes (and the component did after updated) but still renders the previous state! Something weird, that happens when using getDerivedStateFromProp instead of componentWillReceiveProps.
In this case, I have a child component that is used to print/show the data while uses a delete data handler (to remove data from child component interaction). When using getDerivedStateFromProps() I can't access to this.state and the prevState doesn't mean the same since the state is accumulative. And when I remove data from the child component, doesn't update the props to the child (while, using componentWillReceiveProps was OK). So, I'm not find a way to substitute my UNSAFE_componentWillReceiveProps
componentWillReceiveProps:
UNSAFE_componentWillReceiveProps(nextProps){
this.setState({
data: [...this.state.data,...nextProps.data]
})
}
getDerivedStateFromProps:
static getDerivedStateFromProps(nextProps,state) {
console.log("intial state",state)
if (!isEqual(nextProps.data, state.data)) {
return {
data: [...state.data, ...nextProps.data]
};
}
return null;
}
The code
Parent Component:
export class DataConsole extends Component {
// Used for unsubscribing when our components unmount
unsub = null;
static defaultProps = {
data: [],
};
constructor(props) {
super(props);
this.state = {
data: [],
};
this.handleTableRowClick = this.handleTableRowClick.bind(this);
}
UNSAFE_componentWillReceiveProps(nextProps){
this.setState({
data: [...this.state.data,...nextProps.data]
})
}
handleTableRowClick(key) {
console.log(
"handleTable",
key,
this.state.data[key],
this.state.data.length
);
const e = this.state.data.splice(key, 1)
//console.log("remove?", e , this.state.data.length)
this.setState({
undoDataRemove: e
});
}
render() {
return (
<div>
<Container
fluid
style=
className="DataContainer"
>
<Row noGutters>
<Col sm={8} className="ConsoleTable">
<div>
<DataViewer
data={this.state.data}
rowClickHandler={this.handleTableRowClick}
/>
</div>
...
Child Component
export class DataViewer extends Component {
static defaultProps = {
data: [],
};
constructor(props){
super(props)
this.state={data: []}
}
componentDidUpdate() {
console.log("DataViewer updated");
}
static getDerivedStateFromProps(nextProps, prevProps) {
console.log(nextProps, prevProps)
if (!isEqual(nextProps.data, prevProps.data)) {
return {
data: nextProps.data
};
}
return null;
}
render() {
return (
<div className={"TableData"}>
<Table responsive="lg" striped borderless hover>
<tbody>
{this.state.data.map((elem, ids) => {
if (!isEmpty(elem)) {
return (
<tr key={ids} onClick={() => this.props.rowClickHandler(ids)}>
<td>{ids + 1}</td>
{Object.keys(elem).map(function (value, idx) {
return (
<td key={idx}>
{value}:{elem[value]}
</td>
);
})}
</tr>
);
} else {
return null;
}
})}
</tbody>
</Table>
</div>
);
}
}
from Why getDerivedStateFromProps does not allow to re-render with the state update? Not a problem for componentWillReceiveProps - ReactJS
No comments:
Post a Comment