1

I have a class ListItem which is a list of Item. It got some function like setItem that update an item in the list and addItem that add an item and filterItem that set visible

Item is an object that looks like {name,number,discount,visible}

I have a view ListItemView with a pseudo code like this

export default function ListItemView() {

    const [items, setItems] = useState([])

    useEffect(() => {
        setItems(new ListItem(getItems()))
    }, [])
    
    function toggleChange(f,newF){
        setItems((current) => current.setItem(f,newF))
    }

    function filter(search){
        setItems(Items.filterItem({search}))
    }

    return (
        <>
            <button onClick={() => setItems(items.addItem())}> ADD Item</button>
            <input onChange={(e) => filter(e.target.value)} />
            {items.items.map((Item) =>
               !item.visible && item.visible !== undefined  ? null :
               <div key={Item.id}>
                  <ItemLine f={item} toggleChange={toggleChange} />
               </div>
            )}
        </>
    )
}

And ItemLine is just a component that display inputs with the datas of my item

So there is my questions :

  • To update my items, am I forced to use setItems everytimes ? Because it's causing the full rerender of the page, that's quite dumb for me because when we are just setting 1 data in one object of an entire list ?

  • My filter function is quick when I'm typing (to filter on my list), but it's pretty slow when I have to reshow every items in my list, with 300 items it would be unusable, how can I change this ?

  • I have heard of ReactHook form, would it work for me here ?

Thanks for your expertise :)

2
  • "am I forced to use setItems everytimes" Yes, this is how React works. React is pretty optimized out-of-the-box and could easily handle rendering an array of a few hundred elements. Your items state is an array, what is the state updater doing to your state, i.e. what is current.setItem(f,newF)? You are mapping items.items, so now I'm thinking that your items state isn't actually an array and your mounting useEffect is mutating the state shape. Commented Apr 8, 2021 at 6:55
  • I have changed items initial state it should be new ListItem() but my mounting useEffect set items to new ListItem(someitems) where someitems is an array of items that I get from my database. current.setItem(f,newF) will search f the old item in items.items and put newF which is the new item, for exemple a new name. Maybe I should have show ListItem class but it's simply a class with this.items as state Commented Apr 8, 2021 at 7:06

1 Answer 1

2

To update my items, am I forced to use setItems everytimes ? Because it's causing the full rerender of the page, that's quite dumb for me because when we are just setting 1 data in one object of an entire list ?

Yes you need to call setItems to update your state even if it is to add one element or to update one.

However you can optimise on re-renders by converting your mapped values to components and using React.memo to avoid re-renders .

function Item = React.memo(({item, toggleChange}) => {
   return !item.visible && item.visible !== undefined  ? null :
        <div key={Item.id}>
                  <ItemLine f={item} toggleChange={toggleChange} />
         </div>
})
export default function ListItemView() {

    const [items, setItems] = useState([])

    useEffect(() => {
        setItems(new ListItem(getItems()))
    }, [])

    // using useCallback to have only one instaance of toggleChange being created even on re-renders 
    const toggleChange = useCallback(function toggleChange(f,newF){
        setItems((current) => current.setItem(f,newF))
    }, []);

    function filter(search){
        setItems(Items.filterItem({search}))
    }

    return (
        <>
            <button onClick={() => setItems(items.addItem())}> ADD Item</button>
            <input onChange={(e) => filter(e.target.value)} />
            {items.items.map((Item) =>
               <Item key={item.id} item={item} toggleChange={toggleChange}/>
            )}
        </>
    )
}

My filter function is quick when I'm typing (to filter on my list), but it's pretty slow when I have to reshow every items in my list, with 300 items it would be unusable, how can I change this ?

If you are rendering large lists, you should aim towards virtualising those, i.e rendering only items that are in the view. react-window and react-virtualized are popular libraries that you can explore for that.

Sign up to request clarification or add additional context in comments.

2 Comments

If we are taking about performance for writing code in React, I don't know what is right and what is wrong in React , Just blindly believe maybe its ok!
@Nur It is important to try to the code implementation yourself and constantly profile in devtools to understand the impact. React also supports a profiler in latest version to help you with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.