React Hooks依赖关系-无限循环

时间:2019-05-31 17:44:43

标签: reactjs react-hooks

我有以下代码:

void start() {
    // Initialize stuff for the rest of the app
    ApplicationMetrics.initializeMetrics();
}

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

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

所有部门和useCallback都是皮棉react-hooks / exhaustive-deps的建议。所以,我做错了什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

有两个问题。 1.每次获取都会获取一个新值,因为它的状态为依赖项,并且每次都会导致useEffect运行,因此出现了无限循环。 2.useEffect将args作为依赖项,每次也不相同,您不需要传递args来进行获取,因为由于关闭它已经可用。

这是更新的代码,不会无限循环。您可能会遇到皮棉问题,但是在此皮棉变得更加标准之前,您现在应该忽略它们。

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