美文网首页web前端开发
React Hooks 的常见的错误写法

React Hooks 的常见的错误写法

作者: vavid | 来源:发表于2020-07-13 11:29 被阅读0次

一、使用 useState 导致了不必要的重新渲染

错误示例

function ClickButton(props) {
  const [count, setCount] = useState(0);

  const onClickCount = () => {
    setCount((c) => c + 1);
  };

  const onClickRequest = () => {
    apiCall(count);
  };

  return (
    <div>
      <button onClick={onClickCount}>Counter</button>
      <button onClick={onClickRequest}>Submit</button>
    </div>
  );
}

暴露问题 ⚡️
react 中任何 state 更新都会触发组件以及它的子组件重新渲染。上面的示例我们没有在 render 部分用到那些 state,当我们每次设置计数器的时候将会触发不需要的渲染,可能会影响性能或者产生其它副作用。

推荐写法

function ClickButton(props) {
  const count = useRef(0);

  const onClickCount = () => {
    count.current++;
  };

  const onClickRequest = () => {
    apiCall(count.current);
  };

  return (
    <div>
      <button onClick={onClickCount}>Counter</button>
      <button onClick={onClickRequest}>Submit</button>
    </div>
  );
}

二、用 router.push方法替代链接

错误示例

function ClickButton(props) {
  const history = useHistory();

  const onClick = () => {
    history.push('/next-page');
  };

  return <button onClick={onClick}>Go to next page</button>;
}

暴露问题 ⚡️
虽然以上代码大部分场景下没问题,但是当涉及到可访问性时,却有个大问题,因为按钮不会被标记为链接到另一个页面,这使得几乎不可能被屏幕阅读器识别。 另外,你能在一个新的选项卡或窗口中打开它吗? 很可能不能。

推荐写法

function ClickButton(props) {
  return (
    <Link to="/next-page">
      <span>Go to next page</span>
    </Link>
  );
}

三、通过 useEffect 处理 actions

错误示例

function DataList({ onSuccess }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  const fetchData = () => {
    setLoading(true);
    callApi()
      .then((res) => setData(res))
      .catch((err) => setError(err))
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    fetchData();
  }, []);

  useEffect(() => {
    if (!loading && !error && data) {
      onSuccess();
    }
  }, [loading, error, data, onSuccess]);

  return <div>Data: {data}</div>;
}

暴露问题 ⚡️
这里有两个 useEffect hooks 函数,第一个是请求初始化渲染api数据,第二个是在函数加载完毕,没有出错,同时有数据返回时,调用 onSuccess 函数,对吧?
当然对于第一个,永远不可能有问题。但是我们不能保证第一个百分百成功,然后接下来去执行第二个。

推荐写法

function DataList({ onSuccess }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  const fetchData = () => {
    setLoading(true);
    callApi()
      .then((fetchedData) => {
        setData(fetchedData);
        onSuccess();
      })
      .catch((err) => setError(err))
      .finally(() => setLoading(false));
  };

  useEffect(() => {
    fetchData();
  }, []);

  return <div>{data}</div>;
}

四、单一职责的组件

错误示例

function Header(props) {
  return (
    <header>
      <HeaderInner menuItems={menuItems} />
    </header>
  );
}

function HeaderInner({ menuItems }) {
  return isMobile() ? <BurgerButton menuItems={menuItems} /> : <Tabs tabData={menuItems} />;
}

暴露问题 ⚡️
这种写法,使得组件 HeaderInner 承载了两个不同的功能,我们也通过 Mr. Jekyll 知道了一个组件做多件事情并不理想。此外,这样做在其他地方测试或重用组件也更加困难。

推荐写法

function Header(props) {
  return (
    <header>{isMobile() ? <BurgerButton menuItems={menuItems} /> : <Tabs tabData={menuItems} />}</header>
  );
}

五、单一职责的 useEffects

错误示例

function Example(props) {
  const location = useLocation();

  const fetchData = () => {
    /*  Calling the api */
  };

  const updateBreadcrumbs = () => {
    /* Updating the breadcrumbs*/
  };

  useEffect(() => {
    fetchData();
    updateBreadcrumbs();
  }, [location.pathname]);

  return (
    <div>
      <BreadCrumbs />
    </div>
  );
}

暴露问题 ⚡️
这里的 useEffect hook 里有两个功能,一个是“数据获取”,另一个是“展示面包屑”,当数据获取,请求面包屑函数或者 location 发生改变时,useEffect hooks 都会执行。现在的主要问题是,当 location 发生变化时,数据获取函数会重新执行,这可能是我们想不到的一个副作用。

推荐写法

function Example(props) {
  const location = useLocation();

  const updateBreadcrumbs = () => {
    /* Updating the breadcrumbs*/
  };

  useEffect(() => {
    updateBreadcrumbs();
  }, [location.pathname]);

  const fetchData = () => {
    /*  Calling the api */
  };

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <div>
      <BreadCrumbs />
    </div>
  );
}

参考原文

https://www.lorenzweiss.de/common_mistakes_react_hooks/

相关文章

  • React Hooks 的常见的错误写法

    一、使用 useState 导致了不必要的重新渲染 错误示例 ❌ 暴露问题 ⚡️react 中任何 state ...

  • React Hooks用法详解(二)

    React Hooks 在了解React Hooks之前, 我们先看一下 Class 和函数式 的一般写法 Cla...

  • react Hooks

    技术胖博客 React Hooks 类与Hooks 写法对比 先来写一个最简单的有状体组件,点我们点击按钮时,点击...

  • React Hooks

    React Hooks Hooks其实就是有状态的函数式组件。 React Hooks让React的成本降低了很多...

  • React Hooks

    前言 React Conf 2018 上 React 提出了关于 React Hooks 的提案,Hooks 作为...

  • react hooks常见的坑

    useEffect 包含了哪几个生命周期? componentDidMount、componentDidUpdat...

  • react-hooks

    前置 学习面试视频 总结react hooks react-hooks react-hooks为函数组件提供了一些...

  • react-hooks

    react-hooks react-hooks 是react16.8以后,react新增的钩子API,目的是增加代...

  • React-hooks API介绍

    react-hooks HOOKS hooks概念在React Conf 2018被提出来,并将在未来的版本中被...

  • React Hooks 入门

    React Hooks 是 React v16.8 版本引入了全新的 API。 React Hooks 基本概念 ...

网友评论

    本文标题:React Hooks 的常见的错误写法

    本文链接:https://www.haomeiwen.com/subject/vdhmcktx.html