2020年构建React组件(带钩子)时的5个常见错误

图片



你好!在本文中,您将了解创建React组件时最常见的错误,以及为什么将它们视为错误,如何避免或修复它们。



原始材料是由德国开发人员Lorenz Weiss为一个个人博客撰写的,后来收集了很多关于dev.to的正面评论。Quarkly团队专门为Habré社区翻译。





反应



React在Web开发领域已经存在了很长时间,并且它作为敏捷开发工具的地位在最近几年得到了迅速发展。在宣布并发布了新的api /概念钩子之后,创建React组件变得更加容易。



尽管开发React的团队以及使用该语言编写代码的庞大社区都试图对React的概念做出令人印象深刻的解释,但在使用React时,我仍然发现了一些缺点和典型错误。



, , , . , , , , .





, , . . , , , , - . , , , .



React-, , . , , — , . , .



1. useState,



React’ — . . , , , , .



useState , React’. , .



: , , — , . . .



:



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’ , , , .



, , , , . .



:



, , , useRef. , .



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>
  );
}


2. router.push



, React’, , React-.



, , . SPA, . - . React — react-router, .



, ?



:



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

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

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


:



, : , -. , , . ? , .



:



, , <Link> <a>.



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


: !



3. useEffect



, React’, — useEffect. , prop state. , , - .



, DOM. , onSuccess, .



:



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

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

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

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

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


:



useEffect: API , onSuccess. , , , . , ?



, . . 100% , , fetch . , , , .



:



onSuccess , .



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

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

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

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


, onSuccess API.



4.



. ? ? , . .



, , ( isMobile, ).



:



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

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


:



HeaderInner . , . .



:



, , , : , -, .



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


5. useEffect



, componentWillReceiveProps componentDidUpdate React-? , useEffect , .



, useEffect , . , , , (breadcrumbs) ( react-router ).



:



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

  const fetchData = useCallback(() => {
    /*  Calling the api */
  }, []);

  const updateBreadcrumbs = useCallback(() => {
    /* Updating the breadcrumbs*/
  }, []);

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

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


:



: « » (data-fetching) « » (displaying breadcrumbs). useEffect. useEffect , fetchData updateBreadcrumbs location. , fetchData location. , .



:



, , , .



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

  const updateBreadcrumbs = useCallback(() => {
    /* Updating the breadcrumbs*/
  }, []);

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

  const fetchData = useCallback(() => {
    /*  Calling the api */
  }, []);

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

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


: .





React- . , , , , . , - . 100%.



, — , .




All Articles