Reputation: 125
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 :)
Upvotes: 1
Views: 2995
Reputation: 281606
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.
Upvotes: 2