Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What is the best way to manage a number of state of child components in parent component?

I want to manage a number of child components in parent component.

However, when one of child component trigger onCheck event, all child components were re-rendered. (because handleToggleCheck function was changed.)

const Parent = (props) => {
    const {codes} = props // codes is list length 1000

    const [checkedCodes, setCheckedCodes] = useState<Set<string>>(new Set())

    const handleToggleCheck = (code) => {
        if (!checkedCodes.has(code)) checkedCodes.add(code)
        else checkedCodes.delete(code)

        setCheckedCodes(new Set(checkedCodes))
    }

    return (
        codes.map(code => (
            <Child key={code} checked={checkedCodes.has(code)} onCheck={handleToggleCheck} code={code} />
        ))
    }
}

const Child = (props) => {
    const {checked, code, onCheck} = props

    return (
        <input type=“checkbox” checked={checked} onChange={() => onCheck(code)} />
    )
}

I tried to wrap handleToggleCheck function using useCallback, but It doesn’t work because checkedCodes re-maked when called handleToggleCheck.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const handleToggleCheck = useCallback((code) => {
    //…
}, [checkedCodes])

And I tried also use useRef instead of useState, but it doesn’t re-render child component when checkedCodes changed.

//…
const checkedCodes = useRef(new Set())
//…

return (
    codes.map(code => (
        <Child … checked={checkedCodes.current.has(code)} … />
    ))
)

What is the best way?

>Solution :

I tried to wrap handleToggleCheck function using useCallback, but It doesn’t work because checkedCodes re-maked when called handleToggleCheck.

  const handleToggleCheck = useCallback((code) => {
     //…
  }, [checkedCodes])

You can remove checkedCodes as a dependency with a little rewriting:

const handleToggleCheck = useCallback((code) => {
  setCheckedCodes(prev => {
    if (!prev.has(code)) prev.add(code);
    else prev.delete(code);

    return new Set(prev);
  });
}, [])

However, useCallback alone will not prevent the children from being rendered. You will also need to use React.memo to tell react it should skip the component if none of its props have changed:

import { memo } from 'react';

const Child = memo((props) => {
  const {checked, code, onCheck} = props

  return (
    <input type=“checkbox” checked={checked} onChange={() => onCheck(code)} />
  )
})
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading