0

Please take a look at the following code

// index.jsx
 
import React from 'react';
import {data} from '../../../../data.js';
import List from './List.jsx';
 
const peopleContext = React.createContext();
 
export const usePeopleContext = () => React.useContext(peopleContext);
 
const LowerState = () => {
    const [people, setPeople] = React.useState(data);
    const [count, setCount] = React.useState(0);
    const removePerson = (id) => {
        setPeople(currentState => {
            return currentState.filter(item => item.id !== id);
        });
    }
    return (
        <peopleContext.Provider value={{removePerson}}>
            <section>
                <button className='btn' onClick={() => setCount(currentState => currentState + 1)} style={{marginBottom: '1rem'}}>count {count}</button>
                <List people={people}/>
            </section>
        </peopleContext.Provider>
    );
};
 
export default LowerState;
// List.jsx
 
import React from 'react';
import Item from './Person.jsx';
 
const List = ({people}) => {
    return (
        <div>
            {people.map((person) => {
                return <Item key={person.id} {...person}/>;
            })}
        </div>
    );
};
 
export default React.memo(List);
// Person.jsx
 
import {usePeopleContext} from './index.jsx';
 
const Person = ({id, name}) => {
    const {removePerson} = usePeopleContext();
    return (
        <div>
            <h4>{name}</h4>
            <button onClick={() => removePerson(id)}>REMOVE</button>
        </div>
    );
};
 
export default Person;

I am getting the pointless re-rendering of the list when I click the button. I understand that I'm suppose to use the React.useCallback method so that React remembers something so it does not recreate it from scratch. But how would that work for this case? The people={people} (from index.jsx) is whats changing thus the re-render (I think?). So I put the state inside of the useCallback but got another error. How does one go about fixing this? (I did try fixing it by putting the React.useCallback method on the removePerson method for the initial render but it still didn't fix the issue).

Tried to fix pointless re-renders by using the React.useCallback method on the removePerson method but it still didn't work. But I don't think thats the problem? Because from my understanding the use of React.memo on the List component means that it will only re-render when the props on that component change (List). And the people={people} is the only prop on it. So shouldn't I apply some type of React.useCallback on the people? Just some guesses.

IMPORTANT This problem of it still re-rendering only happens when I use the context api with it. But if I were to go the annoying prop drilling route and pass it all the way down to person and add the React.useCallback method on the removePerson I don't get that issue. But I want to learn how to make it work if I were to use the context api. IMPORTANT

Bop 1ABot
  • 1
  • 1
  • What makes you think they're pointless? – evolutionxbox Aug 16 '23 at 13:46
  • @evolutionxbox Well I'm only updating the count. It shouldn't update the List too right? As nothing has changed, so its pointless. Am I missing something? I just started learning about React performance yesterday – Bop 1ABot Aug 16 '23 at 13:59
  • What exactly are you trying to achieve? If you remove an item from a list, the list should re-render. Right? What do you want to achieve with the context? Also, it would be better to separate the context (state and functions) from the components that use it. Maybe it can give you more clarity on how its working. Take a look at [this video](https://youtu.be/piZppPZeeso) (haven't seen it through) to see if it helps your case. – Lalo Mores Aug 16 '23 at 14:00
  • @LaloMores I am trying to stop the re-rendering of the List component everytime I click the button. The context is used so I dont have to prop drill. I just invoke the usePeopleContext and use the method I need. And when it comes to separating the state and functions I did try that but I'm experimenting on how it would work without it. And I will take a look at the video. – Bop 1ABot Aug 16 '23 at 14:04
  • But clicking the button changes the state which the list renders from, why wouldn't you want it to re-render? – evolutionxbox Aug 16 '23 at 14:11
  • @evolutionxbox The button doesn't change anything inside of the actual List. So I wouldn't want it to just re-render right? If the button was suppose to make some change to the actual List that sure that re-render is important. But not for my case. – Bop 1ABot Aug 16 '23 at 14:13
  • `removePerson` changes the `people` state which means the list is re-rendered. This is expected and desired. – evolutionxbox Aug 16 '23 at 14:23

0 Answers0