Does anyone have an example of React.memo() - Trying to prevent a component from re-rendering caused by high up contextual updates.
This component rendered a PayPal Checkout button for instance, so lots of re-renders makes PayPal pretty upset it seems. Dealing with flashing and random loading failures caused by scripts being loading multiple times, dom elements being removed, etc (this is my guess) - So the solution seems to at least try to prevent this from re-rendering so much.
Interesting…but this would not work in this case.
If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result
(https://reactjs.org/docs/react-api.html#reactmemo)
In this case the component does not recieve any props, but updates close to every 16ms with an internal state change through the reducer(s).
Once this happens not all Layers need to update. They only have to update if specific data changes (listed in the dependencies of React.memo).
Also wrapping the Layer components themselves in a pure React.memo call would not work either, because they are recieving functions through the actions prop. Functions are, when you compare them to each other, never the same and woud cause the layers to update even if no data changed.
With React.useMemo, you have to add a dependency array as the second argument (same as useEffect). useMemo will then only compute the function (given in the first argument) again, if one of the dependencies in the dependency array change.
React.memo is similar, but it is a higher order component, not a hook. That means, you can only add it around one of your components.
Looks like wrapping the make function definition in React.memo is indeed sufficient. For example, in the following code, changing the Input’s text will only rerender Counter if the first letter is changed:
module Counter = {
@react.component
let make = React.memo((~prefix) => {
let (count, setCount) = React.useState(() => 0)
Console.log("Counter rendered")
<div>
<p>{String.concat(prefix, Int.toString(count))->React.string}</p>
<button onClick={_ => setCount(c => c + 1)}>{"Increase"->React.string}</button>
</div>
})
}
module Input = {
@react.component
let make = () => {
let (text, setText) = React.useState(() => "")
Console.log("Input rendered")
<div>
<input onChange={c => setText(_ => JsxEventU.Form.target(c)["value"])} value={text}/>
<Counter prefix={text->String.slice(~start=0, ~end=1)} />
</div>
}
}