Suppose you have a component that uses an autocontrolled manager. Let's call it <Number />
.
class Number extends React.Component {
state = {
// Initialize the component class instance with
// the prop you provided from the outside.
number: this.props.number || 0, // defaults to 0
};
// ...rest of the "AutoControlledManager()" implementation
trySetState = NumberAutoControlledManager.trySetState;
// increment state.number then pass that new value to the component's parent callback function.
incrementNumber = () => {
const nextNumber = this.state.number + 1;
this.props.onIncrementClick(nextNumber);
this.setState({ // <-- Updates the number state; Ignores the number prop given by the parent.
number: nextNumber,
});
}
render() {
console.log(this.state.number);
return (
<div>
<button onClick={this.incrementNumber} /> Value: {this.state.number}
</div>
);
}
}
Suppose you have another component on top which contains that component. Let's call it <App />
.
// Number value starts at 0 since we passed nothing.
// A click of the button will add 1 to the number even though we didn't pass a state to it.
const App = <div><Number /></div>;
Suppose you want this <App />
component to control the value displayed. The value starts with 123
, not 0
, and you want to decrement instead of increment.
const App = () => {
const [ value, setValue ] = React.useState(123);
const decrementValue = () => setValue(value => value - 1);
return <div><Number number={value} onIncrementClick={decrementValue} /></div>;
};
See this line?
incrementNumber = () => {
// ...other implementation
this.setState({ // <-- Updates the number state; Ignores the number prop given by the parent.
number: nextNumber,
});
}
With setState
, your number update history will be like this:
123
124
But the parent component asked to decrease the number with its own function, right?
const decrementValue = () => setValue(value => value - 1);
Enter trySetState
:
incrementNumber = () => {
// ...other implementation
this.trySetState({ // <-- Updates the number state only if the number prop wasn't given by the parent.
number: nextNumber,
});
}
123
122
The number would be decreased as expected.