Reputation: 571
Let's have components A and B.
Component B only shows the parent's state in contentForB
in a different format and doesn't manipulate with it. It takes A's state as a prop, applies a function transform(content)
and shows it, so whenever A's contentForB
changes, the new content get transformed and updated in B.
The problem comes when A wants to use B's transformed content and use it somewhere else. I tried to implemented in a standard way, using state-updating function and passed it from A to B like this:
class A extends React.Component {
constructor(props) {
super(props);
this.state = {
contentForB: "",
transformedContent: ""
};
this.updateTransformedContent = this.updateTransformedContent.bind(this);
}
updateTransformedContent(newContent) {
this.setState = { transformedContent: newContent };
}
render() {
return (
...
<B content={ this.state.contentForB }
updateTransformedContent={ this.updateTransformedContent } />
<ComponentUsingTransformedContent transformedContent = { this.state.transformedContent } />
);
}
}
class B extends React.Component {
constructor(props) {
super(props);
this.transform = this.transform.bind(this);
}
transform(content) {
let newContent = ...;
this.props.updateTransformedContent(newContent);
return newContent;
}
render() {
<Something value={this.transform(this.props.content)} />
}
}
However, when A's state changes, B gets reinitialized, it then changes A's state by calling the updateTransformedContent
which again causes B to get reinitialized, thus causing an infinite loop even though the updateTransformedContent
changes the state object which isn't directly passed into B.
Any ideas how to deal with such situation properly?
Upvotes: 1
Views: 55
Reputation: 149
You can use componentDidUpdate lifecycle method.
[codesandbox.io] https://codesandbox.io/s/cool-leaf-92nt8?file=/src/App.js:457-475
class TestB extends Component {
constructor(props) {
super(props);
this.state = {
transformed: ""
};
this.transform = this.transform.bind(this);
}
componentDidUpdate(prevProps) {
if (this.props.content !== prevProps.content) {
this.transform(this.props.content);
}
}
transform(content) {
const transformed = `<h4>${this.props.content}</h4>`;
this.setState({ transformed: transformed });
this.props.updateTransformedContent(transformed);
return transformed;
}
render() {
return (
<div>
<h4>B Componenet:</h4>
<p>{this.state.transformed}</p>
</div>
);
}
}
Upvotes: 1