【问题标题】:React Hooks , function fetchData is not a react component?React Hooks ,函数 fetchData 不是反应组件?
【发布时间】:2019-11-29 20:30:51
【问题描述】:

我正在使用 react hooks 并且在尝试获取一些数据时遇到了一个奇怪的问题,当我创建一个文件以使用 hooks 和 axios 获取数据时

这行得通

import axios from 'axios';

const useResources = (resource) => {
    const [resources, setResources ] = useState([]);

    useEffect(
        () => {
            (async resource => {
                const response = await axios.get(`randomapi.com/${resource}`);
                setResources(response.data);
            })(resource);
        },
        [resource]
    );

    return resources;
};

export default useResources;

但这不是

import { useState, useEffect } from 'react';
import Axios from 'axios';

const fetchData = () => {
    const [data, setData] = useState('');

    useEffect( async () => {
        const response = await Axios('randomapi.com/word?key=*****&number={number_of_words}');
        setData(response.data);
    });

    return data;
};

export default fetchData;

'React Hook useEffect 包含对'setData'的调用。如果没有依赖项列表,这可能会导致无限的更新链。要解决此问题,请将 [] 作为第二个参数传递给 useEffect Hook。'

他们不一样吗?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    乍一看,它们很相似,但它们仍然存在差异。 让我们检查一下:

    useEffect(
            () => {
                // we create a function, that works like a "black box" for useEffect
                (async resource => { 
                    const response = await axios.get(`randomapi.com/${resource}`);
                    // we don't use `setResources` in dependencies array, as it's used in wrapped function
                    setResources(response.data); 
                // We call this function with the definite argument
                })(resource); 
    
            // this callback doesn't return anything, it returns `undefined`
            },    
    
             // our function depends on this argument, if resource is changed, `useEffect` will be invoked
            [resource] 
        );
    

    useEffect钩子应该接收一个函数,该函数可以返回另一个函数来处理所有动态数据,监听器(例如删除事件监听器,清除超时回调等)

    下一个例子:

    // this function returns a promise, but actually useEffect needs a function, 
    // which will be called to dispose of resources. 
    // To fix it, it's better to wrap this function 
    // (how it was implemented in the first example)
    useEffect( async () => { 
            const response = await Axios('randomapi.com/word?key=*****&number={number_of_words}');
            setData(response.data);
    // we don't set up an array with dependencies. 
    // It means this `useEffect` will be called each time after the component gets rerendered. 
    // To fix it, it's better to define dependencies
    }); 
    

    所以,我们有两个主要错误:

    1) 我们的 useEffect 回调返回一个 Promise 而不是函数,它实现了 dispose 模式

    2) 我们错过了依赖数组。因此,组件将在每次更新后调用 useEffect 回调。

    让我们修复它们:

    useEffect(() => {// we wrap async function: 
      (async () => { 
         // we define resource directly in callback, so we don't have dependencies:
         const response = await Axios('randomapi.com/word?key=*****&number={number_of_words}');
         setData(response.data);
      })()  
    }, []); 
    

    最后,我们修复了第二个示例 :) 我什至用自定义 fetchData 钩子和 useEffect 的最终版本做了一个例子:https://codesandbox.io/s/autumn-thunder-1i3ti

    有关useEffect 的依赖项和重构提示的更多信息,您可以在此处查看:https://github.com/facebook/react/issues/14920

    【讨论】:

      猜你喜欢
      • 2021-04-07
      • 2019-04-16
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多