What’s a derived state? Think one state for text
and then another for uppercaseText
.
Derived State
function Foo() {
const [text, setText] = useState('hello, za warudo!');
const [uppercaseText, setUppercaseText] = useState(text.toUpperCase());
useEffect(() => {
setUppercaseText(text.toUpperCase());
}, [text])
...
}
Putting like that it’s crazy to think anyone would do this… right? RIGHT?
Yes, an example like this will make clear that this is wrong.
The Bad of Derived State
- Stored separately and out-of-sync with the actual state.
- Triggers (depend) on unnecessary re-renders.
How to refactor the derived state?
Say it’s an expensive calculation… the solution is to use useMemo
.
function Foo() {
const [text, setText] = useState('hello, za warudo!');
const uppercaseText = useMemo(() => text.toUpperCase(), [text]);
...
}
How to quickly spot state that can be derived?
I came up with a good way of thinking that should make it easier to KNOW if a state should be “another state” or just a computed property (memorized or not depending on the case).
function Foo({
text = 'hello, za warudo!',
uppercaseText = text.toUpperCase(),
}) {
...
}
// Forget react for a moment...
// Would you ever call a function like this?
const text = 'hello, za warudo!';
Foo({
text,
uppercaseText: text.toUpperCase(),
});
If you think of those states as “props”, then this makes it more blatantly what it should be.
Forget React entirely, think only of functions:
Would you call a function with a variable and then another variable you could just compute inside?