I understand React Native re-renders component in which setState is called.
In example as I tested, there are 7 re-renders per 7 setStates in useEffect codes:
const pullData = async (numToPull, filterPull, sorterPull) => {
setToSpin(true);
const response = await AxiosPost(
sc.Slink.getMailInbox,
{
page: 1,
pageSize: numToPull,
filterOption: [
...filterPull,
{
key: "isUnread",
value: true,
},
],
sortOption: sorterPull,
},
{ Authorization: ctxt.authInfo.tokenSF },
{ studio: ctxt.roomInfo.currentLoginRoom }
);
setToSpin(false);
if (response.data.suc) {
setShowList(response.data.data.items);
setNumOfDataPulled(response.data.data.items.length);
setSearchKey("");
setCurrentFilter(filterPull);
setCurrentSorter(sorterPull);
} else setSmsg(response.data.msg);
};
useEffect(() => {
pullData(sc.Snumber.numToPullMail, [], []);
}, []);
I’m wondering is this a designed mechanism in React Native? or there are other ways to reduce render-times?
Above example is simple in my project though – I have some complex components in which have more than 20 setState in-used, also with ~10 functions in each component. If setState causes re-render 20+ times plus re-creation of functions, the resource waste is probably considerable…
I don’t want to use Redux, useCallback and would like know 1) is this normal in React Native world? (render 20 times for any component); 2) is there smarter way to avoid resource waste in virtual DOM comparision? (in example above, I didn’t see any reason have to render component 5 times for codes written in sequence
setShowList(response.data.data.items);
setNumOfDataPulled(response.data.data.items.length);
setSearchKey("");
setCurrentFilter(filterPull);
setCurrentSorter(sorterPull);
)
Thanks!
2
Answers
If you use react 18 (which was enabled by default in React Native 0.69), setting multiple states like this will do just one render:
Prior to react 17, react could usually batch them together, but not always. One of those cases which did not work was the one you have in your example: in an async function after an await. For this case, each of the calls to set state would cause its own render, not a single batched one.
In react 17 you can force these to be batched by the use of
unstable_batchedUpdates
:The behavior you’re observing is a common characteristic of React and React Native, known as "reconciliation". When a component’s state changes, React checks to see if any of the component’s child elements need to be re-rendered. If any of the child elements need to be updated, then the entire component is re-rendered.
In the example you provided, the component is re-rendered 7 times because there are 7 state updates triggered by the set functions inside the pullData function. This is a normal behavior in React and React Native, and it is how the framework ensures that the UI is always up-to-date with the application’s state.
Here’s a way you could resolve this by React.Memo