【问题标题】:Custom React hook for fetching data is not working correct用于获取数据的自定义 React 钩子无法正常工作
【发布时间】:2022-01-01 18:08:19
【问题描述】:

我有这个用于从 API 获取数据的自定义 React 钩子:

import { useState, useEffect } from 'react';

const API_CHARACTERS = 'https://rickandmortyapi.com/api/character';

export const useFetchData = () => {
  const [data, setData] = useState();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);

    fetch(API_CHARACTERS)
      .then((response) => response.json())
      .then((data) => setData(data))
      .catch(() => setError('Data fetching is failed!'))
      .finally(() => setLoading(false));
  }, [])

  return { data, loading, error }
}

为了与正在获取的数据进行交互,我有这个组件

import React from 'react';
import './app.css';

import { useFetchData } from './hooks/useFetch';

function App() {
  const { data, loading, error } = useFetchData();
  console.log(data)


  return (
    <div className="App">
    </div>
  )
}

export default App;

当我试图处理 data 变量时 - 一切都很好。但是当我试图获得类似 data.results 的东西时,我会在下次刷新页面后得到这个: error image

【问题讨论】:

    标签: reactjs react-hooks state use-effect use-state


    【解决方案1】:

    完成异步任务(AJAX 调用)需要一些时间。您可以使用 useEffect 和依赖数组来检查数据是否可用。

    const API_CHARACTERS = "https://jsonplaceholder.typicode.com/users";
    
    const useFetchData = () => {
      const [data, setData] = React.useState([]);
      const [loading, setLoading] = React.useState(false);
      const [error, setError] = React.useState(null);
    
      React.useEffect(() => {
        setLoading(true);
        fetch(API_CHARACTERS)
          .then((response) => response.json())
          .then((data) => setData(data))
          .catch(() => setError("Data fetching is failed!"))
          .finally(() => setLoading(false));
      }, []);
    
      return { data, loading, error };
    };
    
    const App = () => {
      const { data, loading, error } = useFetchData();
      
    
     React.useEffect(() => {
        console.log(data); // called once data will change
      }, [data]);
    
      if (loading) {
        return <div className="App">Loading... </div>;
      }
    
      if (error) {
        return <div className="App">{JSON.stringify(error)}</div>;
      }
    
      return (
        <div className="App">
          {data?.map((item) => {
            return <div key={item.id}>{item.name}</div>;
          })}
        </div>
      );
    };
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.production.min.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"
    ></script>
    <div id="root"></div>

    useEffect 的Dependencies 参数是useEffect(callback, dependencies)

    让我们探索副作用和运行:

    未提供:每次渲染后都会运行副作用。

     import { useEffect } from 'react';
        
        function MyComponent() {
          useEffect(() => {
            // Runs after EVERY rendering
          });  
        }
    

    一个空数组[]:副作用在初始渲染后运行一次。

     import { useEffect } from 'react';
        
        function MyComponent() {
          useEffect(() => {
            // Runs ONCE after initial rendering
          }, []);
        }
    

    有 props 或 state 值[prop1, prop2, ..., state1, state2]:只有在任何依赖值发生变化时才会产生副作用。

    import { useEffect, useState } from 'react';
    
    function MyComponent({ prop }) {
      const [state, setState] = useState('');
      useEffect(() => {
        // Runs ONCE after initial rendering
        // and after every rendering ONLY IF `prop` or `state` changes
      }, [prop, state]);
    }
    

    【讨论】:

      【解决方案2】:

      因为api call 需要一些时间,所以您的控制台不会立即打印。可以使用useEffect钩子查看数据:

      useEffect(() => {
          if (data) {
            console.log(data.results, "result");
          }
        }, [data]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-07
        • 2019-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 2021-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多