DEV Community

Discussion on: React lists without .map

Collapse
dikamilo profile image
dikamilo • Edited on

React lists without map and still uses map but hidden deep inside after refactoring ;)

You repeat list is still rerendered as whole when you add or remove elements. You can see it in devtools react profiler.

Each RenderItem is rerendered because remove prop change every time, you can fix it by wrapping remove function with useCallback. But RenderItem will still be rerendered in other cases because parent compontent rerenders each time. This can be fixed by using memo on RenderItem and removing index prop from item.type because it changes every time and causes rerenders on children component.

After this, adding new element will render only one RenderItem and removing item will just remove single component.

Cheers

Collapse
miketalbot profile image
Mike Talbot Author

Well you don't use a .map when you make this list was my point ;)

Good point on the remove - I'd do that by using a useCallback if I'd remembered lol:

function App4() {
    const [render, setRender] = useState(items)
    const remove = useCallback(_remove, [])
    return (
        <Box>
            <List className="App">
                <Repeat list={render}>
                    <RenderItem remove={remove} />
                </Repeat>
            </List>
            <Button variant="contained" color="primary" onClick={add}>
                Add
            </Button>
        </Box>
    )

    function add() {
        setRender((items) => [
            { name: "Made up at " + Date.now(), on: false }
            ...items,
        ])
    }

    function _remove(item) {
        setRender((items) => items.filter((i) => i !== item))
    }
}
Enter fullscreen mode Exit fullscreen mode

The index property is important for many things that require sorting etc and while the component will be called when you update the list it then shouldn't be creating a new element if the index stays stable (as I'm inserting at the top of the list that isn't likely)