防止重新渲染

问题描述 投票:0回答:1

帮助解决Row组件重新渲染的问题。 我有一个父 List 组件,里面有一个 Row 组件列表。 Row里面有一个渲染计数器,renders。 我需要当一行的检查发生变化时,只有该行的渲染计数器发生变化。其余的应该保持不变。

function getList() {
    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            resolve(
                Array.from({ length: 10 }, (_el, index) => ({
                    label: `label ${index + 1}`,
                    checked: false,
                    id: index,
                }))
            );
        }, 1000);
    });
}
const Row = memo(({ label, checked, id, handleChange }) => {
    const renders = useRef(0); // следит за ререндером

    const handleCheckboxChange = () => {
        handleChange(id);
    };

    return (
        <div>
            {label}
            {` (${renders.current++}) `}
            <input
                type='checkbox'
                checked={checked}
                onChange={handleCheckboxChange}
            />
        </div>
    );
});
const List = ({ list, setList }) => {
    const handleChange = (id) => {
        const updatedList = list.map((item) => {
            if (item.id === id) {
                return { ...item, checked: !item.checked };
            }
            return item;
        });
        setList(updatedList);
    };

    // if (!list.length) {
    //     return <div>LOADING...</div>;
    // }

    return (
        <>
            {list.map((item) => (
                <Row key={item.id} {...item} handleChange={handleChange} />
            ))}
        </>
    );
};
const Test = () => {
    const [rows, setRows] = useState([]);

    useEffect(() => {
        getList().then((res) => {
            setRows(res);
        });
    }, []);

    return (
        <div className='test'>
            <h1>Test</h1>
            <List list={rows} setList={setRows} />
        </div>
    );
};

export default Test;

尝试使用 React .memo() 和 useCallback()。但这并没有产生结果。

reactjs react-hooks react-memo react-usecallback
1个回答
0
投票

每次渲染时都会重新创建

handleChange
函数,这会导致所有
Row
组件重新渲染。

handleChange
包裹
useCallback
。为了避免将
list
设置为依赖项,请将更新程序函数传递给
setList
。使用当前状态值调用更新器函数。

const handleChange = useCallback(id => {
  setList(prevList => prevList.map(
    item => item.id === id 
      ? { ...item, checked: !item.checked } 
      : item
  ));
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.