Reputation: 1193
Okay. Here is my situation. I have a big component called TheForm
. In TheForm
, there are the following children: TextEditor
, TagInput
, TipCard
- this gives the advice how to write a good form and Preview
:
const TheForm = () => {
const [parag1, writeParag1] = useState("");
const [parag2, writeParag2] = useState("");
const [tags, updateTags] = useState([]);
return (
<div>
<TipCard>Some suggestion here...</TipCard>
Paragraph One: <TextEditor onInput={writeParag1}/>
Paragraph One: <TextEditor onInput={writeParag2}/>
Add tags: <TagInput onInput={updateTags}/>
Preview Mode: <Preview />
<button>Submit</button>
<button>Reset</button>
</div>
);
}
The TextEditor
contains a <textarea>
, some buttons to format text, everytimes the value of the <textarea>
changes, the proper state in TheForm
is updated. Same for TagInput
.
The Preview
will take the state values and render them in preview mode (just like Stack Overflow ask a question).
The problem here is when one of the states is updated, it causes all the children re-rendered, even they are not using that state and even I used the React.memo
for the component.
I know that when the state changes, it make the component re-rendered, so the children of the component are re-rendered too.
So how can I avoid that? I know that I can move the states down to the children, but if I do it, the Preview
can not access those value. Redux can solve this problem, but is it too much to use Redux here, I mean those states are not shared with other component so using Redux is too much?
Upvotes: 0
Views: 446
Reputation: 12727
It is just how React works - it run render function every time state is changed and it cause all children to re-render too, no matter are they depended on changed state or not.
If you would like to avoid re-render of a component, you can make it pure, e.g. wrap it with React.memo
. So you have to wrap each child in order to prevent it re-render.
Pure components shallow compare props
to determinate if it safe to skip re-render requested from a parent. It means, you have to not only wrap children to memo
but ensure the props passed to them is persistent each time of render.
Usually it means you should memoize callback like
onInput={el => updateTitle(el.target.value)}
with useMemo
or useCallback
and avoid, flatten or memoize objects like previewMode={{ title, description, codeBlock, tagList }}
otherwise they will be re-created each time and it will invalidate shallow-compare optimisation
Upvotes: 1