发布于 2026-01-05 12 阅读
0

你(可能)不需要 useState + useEffect。

你(可能)不需要 useState + useEffect。

`and`useState和 ` useEffecthooks` 对 React 社区来说简直是天赐之物。然而,任何工具都一样,它们也很容易被滥用。

以下是我在软件开发生涯中经常看到的一种误用示例:

const MyAwesomeComponent = () => {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState();
  // ---- PROBLEMATIC HOOKS: ----
  const [items, setItems] = useState([]);
  const [itemsLength, setItemsLength] = useState(0);

  useEffect(() => {
    someAsyncApiCall().then(res => {
      setData(res.data);
      setLoading(false);
    });
  }, [setData, setLoading]);

  // ---- UNNECESSARY USAGE OF HOOKS: ----
  // anytime data changes, update the items & the itemsLength
  useEffect(() => {
    setItems(data.items);
    setItemsLength(data.items.length || 0);
  }, [data, setItems, setItemsLength]);

  return (
    // ...JSX
  );
};
Enter fullscreen mode Exit fullscreen mode

上述用例的问题在于我们跟踪了一些冗余状态,具体来说是itemsitemsLength。这些数据可以通过函数从 中导出data

更好的方法:

任何可以从其他数据推导出的数据都可以用纯函数进行抽象和重写。

其实这很容易做到——举个例子:

const getItems = (data) => {
  // I always like to protect against bad/unexpected data
  if (!data || !data.items) return [];

  return data.items;
};

const getItemsLength = (data) => {
  return getItems(data).length;
};
Enter fullscreen mode Exit fullscreen mode

然后,我们的组件简化为以下形式:

const MyAwesomeComponent = () => {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState();

  // DERIVED DATA - no need to keep track using state:
  const items = getItems(data);
  const itemsLength = getItemsLength(data);

  useEffect(() => {
    someAsyncApiCall().then(res => {
      setData(res.data);
      setLoading(false);
    });
  }, [setData, setLoading]);

  return (
    // ...JSX
  );
};
Enter fullscreen mode Exit fullscreen mode

要点总结

这种模式的优点在于,对于给定的输入,输出始终相同,因此很容易为其编写单元测试getItemsgetItemsLength

或许上面的例子有点牵强,但这绝对是我多年来在很多代码库中看到的一种模式。

随着应用程序规模的扩大,尽可能降低复杂性对于避免技术债务至关重要。

tl;dr:

使用useState钩子useEffect函数往往不可避免,但如果可以,尽量将任何可以从其他数据派生出来的数据抽象出来,使用纯函数。这样做的好处会在日后带来巨大的回报。

横幅照片由Lautaro AndreaniUnsplash上拍摄

文章来源:https://dev.to/townofdon/you-probously-dont-need-that-usestate-useeffect-3ijh