最近我玩了 React-hooks 来处理大量从数组迭代的表单字段。 我的目标是防止在未更改的字段组件上不必要的重新渲染。我用这段代码实现了它,但仍然有一些问题悬而未决:
import React, { useState, useCallback, useRef, useEffect } from 'react';
export default function Multipleform() {
// use useRef to prevent re-render of component due to state change
// create empty array with length of n
let data = useRef([...Array(5000).fill('')]);
let [reloader, setReloader] = useState(0);
// wrap handler with useCallback to keep its reference
// so React.memo will not consider it change overtime
const handler = useCallback((e, i) => {
// change state to rerender component, so i can see changes in ref
setReloader((val) => val + 1);
data.current[i] = e.target.value;
}, []);
return (
<div>
<h1>Form</h1>
{/* to log current state */}
<button onClick={() => console.log(data.current)}>log state</button>
{/* just print string of array to see state (ref value) changes */}
<p>{data.current.filter(Boolean).toString()}</p>
{data.current.map((x, i) => {
return (
<MemoizedField data={x} key={i} handler={(e) => handler(e, i)} />
);
})}
</div>
);
}
const MemoizedField = React.memo(
({ data, handler }) => {
useCountRenders();
return <input value={data} onChange={handler} />;
},
// 1. why should i put this, if React.memo itself will prevent re-render if no props changed?
(prev, next) => prev.data === next.data
);
// custom hooks to see re renders count of certain component
export const useCountRenders = () => {
const renders = useRef(0);
useEffect(() => console.log('renders: ', renders.current++));
};
- 在评论中也是如此,如果 React.memo 本身在没有更改道具的情况下会阻止重新渲染,我为什么要放置上一个和下一个比较?
- 我对上面的钩子用法的理解是否有误解?
- 代码是否足够好,或者我可以改进它吗?
谢谢
我认为其余看起来都很好。 这里似乎有问题
<MemoizedField data={x} key={i} handler={(e) => handler(e, i)} />
您应该直接使用处理程序,否则 useCallback 将没有任何效果。在每次渲染时,都会创建函数。
<MemoizedField data={x} key={i} handler={handler} />