The state for my project includes a list of nested animals eg:
{"europe":{"air":{name:"warbler", points:0}}}
My components are generated based on this data, and at the lowest level (the animal itself), there is a button which is currently triggering a series of callbacks to the highest level, starting a dispatch to the reducer. Every time a button is clicked, all the components from every continent re-render. Would it be better to implement useContext, even though every level of component requires some amount of data from the state object? I tried to implement useCallback, to prevent re-rendering but I didn't know which callbacks were causing it. What would be the best way to optimize rendering a series of nested components (without redux)?
Inside App component
{Object.entries(state.animalData).map(([continent, areas]) => (
<Continent
key={continent}
areas={areas}
totals={state.totals.continents[continent]}
handleVote={(
num: number,
animal: string,
area: string
) => triggerChange(num, animal, area, continent)}
/>
))}
Inside Continent component
<Area
key={area}
area={area}
animals={animals}
onVote={(num: number, animal: string) =>
handleVote(num, animal, area)
}
/>
Inside Area component
{animals.map(animal => (
<Animal
key={animal.name}
animal={animal}
voted={(num: number) => onVote(num, animal.name)}
/>
))}
Inside Animal component
<div>
<h4>{animal.name}</h4>
<div>
<button onClick={voted(+1)}> Upvote </button>
<button onClick={voted(-1)}> Downvote </button>
</div>
<h4>{`${animal.points} Points`}</h4>
<hr />
</div>
Your components trigger a re render because you are using inline defined functions everywhere and those aren't referentially stable. You can use the
useCallback
(https://reactjs.org/docs/hooks-reference.html#usecallback) hook to prevent re renders.But you could also use a context provider (as you suggested) which holds the
voted
callback. That way you don't have to use prop drilling to get the function to the component where it is needed.The basic solution for this is explained in detail here: https://medium.com/@jeromefranco/how-to-avoid-prop-drilling-in-react-7e3a9f3c8674