reactjs - 为什么自定义钩子(Hook)返回结果两次

标签 reactjs react-hooks

下面的文章是关于创建用于获取数据的自定义 Hook ,而且很简单。

https://dev.to/patrixr/react-writing-a-custom-api-hook-l16

有一个部分我不明白它是如何工作的。

为什么这个钩子(Hook)会返回两次结果? (isLoading=true isLoading=false)

function useAPI(method, ...params) {
    // ---- State
    const [data, setData]           = useState(null);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError]         = useState(null);

    // ---- API
    const fetchData = async () => {
      onError(null);
      try {
        setIsLoading(true);
        setData(await APIService[method](...params));
      } catch (e) {
        setError(e);
      } finally {
        setIsLoading(false);
      }
    };

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

    return [ data, isLoading, error, fetchData ];
}


function HomeScreen() {
  const [ users, isLoading, error, retry ] = useAPI('loadUsers');

  // --- Display error
  if (error) {
    return <ErrorPopup msg={error.message} retryCb={retry}></ErrorPopup>
  }

  // --- Template
  return (
    <View>
      <LoadingSpinner loading={isLoading}></LoadingSpinner>
      {
          (users && users.length > 0) &&
            <UserList users={users}></UserList>
      }
    </View>
  )

最佳答案

React 在事件处理程序生命周期方法中批量进行状态更新。

fetchData 不是其中任何一个,因此不会发生批处理。

现在,当调用fetchData()时:

const fetchData = async () => {
  onError(null);
  try {
    // #1 async setState
    setIsLoading(true);

    const data = await APIService[method](...params);

    // #2 async setState
    setData(data);

  } catch (e) {
    setError(e);
  } finally {

    // #3 async setState
    setIsLoading(false);
  }
};

成功时,有 3 个异步事件,我们只对 #1#3 感兴趣

  • 将加载状态从默认值 false 设置为 true
  • #1 异步 setState 将加载状态设置为 false

Side Note: From first glance this hook has flaws, fetchData is re-assigned on every render and you will get missing dependencies warnings.

关于reactjs - 为什么自定义钩子(Hook)返回结果两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59547504/

相关文章:

reactjs - useEffect 缺少依赖项

javascript - React Hook - 只监听窗口 *宽度* 大小的变化

javascript - react : Looping over an object to bind useState functions is not updating the state of my application

reactjs - React useRef 不适用于 Material UI TextField

javascript - 无法使用事件监听器第二次切换组件

css - 带样式的组件可以像 SCSS 一样处理计算吗?

javascript - 如何在 native react 中添加动态输入?

javascript - 在 AJAX 请求中 React useState() 不会改变组件状态

javascript - 在 react-router v6 的 mapStateToProps 中使用 urlParams

javascript - 我的 CSS 样式表对我的 React 组件没有影响