React Hooks 依赖 - 无限循环 [英] React Hooks Dependencies - Infinite Loop

查看:64
本文介绍了React Hooks 依赖 - 无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

import React from "react";

export const useFetch = (promise, args = [], options = {}) => {
  const [state, setState] = React.useState({
    loading: false,
    data: null,
    error: null
  });

  if (!args) args = [];

  const fetch = React.useCallback((...args) => {
    setState({
      ...state,
      loading: true,
      error: null
    });

    return promise(...args)
      .then(response => {
        setState({
          ...state,
          loading: false,
          data: response
        });
        return response;
      })
      .catch(error => {
        setState({
          ...state,
          loading: false,
          error
        });
      });
  }, [promise, state]);

  React.useEffect(() => {
    if (options.now) {
      fetch(...args);
    }
  }, [args, fetch, options.now]);

  return {
    fetch,
    ...state
  };
};

但是当我尝试这样使用时,我得到了一个无限的 console.log 循环:

const allUsers = () => Promise.resolve([{ name: 'Bruno' }])

function App() {
  const { data } = useFetch(allUsers, [], { now: true })
  console.log('->', data)
  return (
    <span>Testing hook</span>
  )
}

所有的 deps 和 useCallback 都是来自 lint react-hooks/exhaustive-deps 的建议.那么,我做错了什么?

All the deps and the useCallback was suggestions from the lint react-hooks/exhaustive-deps. So, what I'm doing wrong?

感谢您的帮助.

推荐答案

有 2 个问题.1. 你的 fetch 每次都会得到一个新值,因为它有状态作为依赖,这导致 useEffect 每次都运行,所以无限循环.2.useEffect 有 args 作为依赖,每次都不一样,你不需要传递 args 来获取,因为它已经可用了,因为闭包.

There are 2 problems. 1. Your fetch is getting a new value every time as it has state as a dependency and that is causing useEffect run every time, so infinite loop. 2.useEffect has args as a dependency which is also not the same every time, you don't need to pass args to fetch as it's already available because of closure.

这是一个不会进入无限循环的更新代码.你可能会遇到 lint 问题,但你应该暂时忽略它们,直到这个 linter 变得更加标准.

here is an updated code that doesn't go in an infinite loop. you might get lint issue but you should ignore them for now until this linter becomes more standard.

const useFetch = (promise, args = [], options = {}) => {
  const [state, setState] = React.useState({
    loading: false,
    data: null,
    error: null
  });

  if (!args) args = [];

  const fetch = React.useCallback(() => {
    setState({
      ...state,
      loading: true,
      error: null
    });

    return promise(...args)
      .then(response => {
        setState({
          ...state,
          loading: false,
          data: response
        });
        return response;
      })
      .catch(error => {
        setState({
          ...state,
          loading: false,
          error
        });
      });
  }, [promise]);

  React.useEffect(() => {
    if (options.now) {
      fetch();
    }
  }, [fetch, options.now]);

  return {
    fetch,
    ...state
  };
};

const allUsers = () => Promise.resolve([{ name: 'Bruno' }])


const App = props => {
  const { data } = useFetch(allUsers, [], { now: true });
  console.log(data, "=>");
  return <input name="name" onChange={this.handleInputChange} />;
}

这篇关于React Hooks 依赖 - 无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆