在React Hooks之前,我有这样的代码:
interface State {
f1: number;
f2: number;
}
class OldClassParent extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
f1: 0,
f2: 0
};
}
public render() {
const { f1, f2 } = this.state;
return (
<>
{/* Each pure component re-render only if its value has changed (OK) */}
<MyPureCmp value={f1} name="f1" onChange={this.onChange} />
<MyPureCmp value={f2} name="f2" onChange={this.onChange} />
</>
);
}
private onChange = (name: string, newValue: number) => {
// @ts-ignore
this.setState({
[name]: newValue
});
}
}
现在,我尝试对React-hooks采取相同的行为。我做了以下事情:
const NewHookParent: React.FC = () => {
const [state, setState] = useState({
f1: 0,
f2: 0
});
// useCallback does not help me here
const onChange = useCallback((name: string, newValue: number) => {
setState({...state, [name]: newValue});
}, [state, setState]);
const { f1, f2 } = state;
return (
<>
{/* Each pure component re-render when any value change
as the onChange handler is never the same (NOT OK) */}
<MyPureCmp value={f1} name="f1" onChange={onChange} />
<MyPureCmp value={f2} name="f2" onChange={onChange} />
</>
);
}
问题是我失去了以前的重新渲染优化。 在此示例中,为简单起见,我仅使用了两个字段,但实际上我可能拥有任意多个字段(而且它可以是动态的,在编译时未知)。 我该怎么办?
答案 0 :(得分:1)
由4
产生的setState
函数接受一个更新程序函数。以当前状态调用更新程序。使用此功能,替换操作会将状态传递给useState
,并且由于useCallback
本身不会更改,因此setState
将始终返回相同的函数。
useCallback