I have a Card component, which gets passed a CryptoAsset
instance. The class stores relevant information such as Assets ticker, amount, value, etc.
I tried to use an useEffect
hook in the beginning to track if the class information gets changed, and for some reason it is not firing unless the component has re-rendered after it’s values updated.
(I have updatePrice method, which changes the current CryptoAssets price)
So I simply have created an useState
which is used only for the re-rendering the component.
const Card = ({ asset }: CardProps) => {
// Using an array destructuring to get the setRefresh function.
const [, setRefresh] = useState(0);
useEffect(() => {
asset.updatePrice();
refresh();
},[asset])
const refresh = () => {
setRefresh((prevValue) => prevValue + 1);
};
I have removed the first variable from the array so it doesn’t give me an unused var warning.
But this leaves me with a question, if the CryptoAssets
values change in future, would it be possible to track it with useEffect
? Or do I always have to invoke the refresh function in order to keep the component with correct information? And is this a correct way of doing this?
2
Answers
React components rerender for a few reasons:
Ideally in React you would update an entire reference to an object that is stored in state and this will automatically trigger a component rerender. This is the typical shallow copying of arrays and objects into new array and object references, a pattern commonly referred to as the Immutable Update Pattern.
Examples:
However
Sometimes you might find yourself working with a non-React library that may utilize OOP patterns. It’s often the case here that you will instantiate an instance of this Class object and store it in a React ref. It’s impractical, and maybe even not possible, to just clone the object into a new instance each time you are updating its state. This is an edge case where it is acceptable to implement "forceUpdate" logic in a component.
This would effectively be the React function component equivalent to the React Class component forceUpdate lifecycle method. From the documentation, I’ve emphasized the related use case.
It’s included as an escape hatch and should be used sparingly, basically as a "last resort" if there is not any immutable way to work with the external objects.
You don’t need to output it to the refresh function but can edit the
useState
inside theuseEffect
: