自定义挂钩导致性能不佳,尽管使用 useCallback 进行优化不会反映新状态

Custom hook cause poor performance, although optimizing with useCallback will not reflect the new state

我正在做一些 React Hooks 实验,遇到了一个漂亮的轰炸问题。

我正在尝试创建自定义表单状态挂钩。 我创建了一个非常非常简化的版本 我的工作只是为了证明这里的问题:https://repl.it/@kadoshms/useCallbackCapture

代码本身在这里(为了简单起见,我将所有代码放在同一个主文件中):

import React, { Component, useState, useCallback } from 'react';
import logo from './logo.svg';
import './App.css';

const myHook = (e) => {
  const [values, setValues] = useState({
    checked: []
  });

  const setFormValues = useCallback((e) => {
    // some logic 
    if (e.currentTarget.checked) {
      setValues({
        checked: [...values.checked, e.currentTarget.value] 
      });
    } else {
      setValues({
        checked: values.checked.filter(v => v !== e.currentTarget.value)
      });
    }
  }, []);

  return [values, setFormValues];
}

const checkboxes = Array.from({length: 222}, (v, k) => k+1); 

const Checkbox = (props) => (
  <input type="checkbox"
      name={props.name}
      value={props.value} 
      checked={props.checked} onChange={props.onChange} />
);

// Checkbox.whyDidYouRender = true;

const Form = () => {
  //
  const [formData, setFormData] = myHook();
  return (
    <form>
      {checkboxes.map((c) => <Checkbox name="foo" checked={formData['checked'].includes(c.toString())}
       key={`c-${c}`} 
      onChange={setFormData} value={c} />)}
    </form>
  );
  //
};

class App extends Component {
  render() {
    return (
      <div className="App">
        <Form />
      </div>
    );
  }
}

export default App;

这个问题在我提供的示例中几乎是不言自明的。 useCallback 挂钩可能会捕获导致 checked 数组不更新的最后状态。 添加 formData 作为依赖项,或者另一方面删除记忆将修复它。 不过,这可能会导致性能问题,因为 onChange 处理程序在每次渲染时都会关闭。

我的目标是使用 hooks 但保持良好的性能,因此每个复选框只有在 checked 值更改时才应该更新。

编辑: 我可以使用自定义 React.memo 回调解决问题,类似于 shouldComponentUpdate,但我认为它不太优雅。

这可能吗?

提前致谢。

进一步阅读后,我在 React 官方文档中遇到了以下常见问题解答部分:https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-because-of-creating-functions-in-render

TL:DR: 我没有使用 useState,而是使用 useReducer 钩子创建了一个 reducer,就像文档中指定的那样。 如果有人感兴趣,我很乐意分享我针对上述特定问题的解决方案。