组件在反应中渲染了6次

时间:2020-08-19 03:34:44

标签: reactjs api react-hooks

我正在尝试使用自定义钩子来调用API来获取数据。然后,我尝试在我的Context API中调用该钩子。问题在于,钩子的主体被渲染了6次。因此,当我尝试使用自定义钩子(useFetchData)返回的数据在Context文件中设置setState时,出现错误-“错误:重新渲染太多。React限制了渲染数量,以防止无限循环。” 。我认为某些状态更改导致其重新呈现。

context.js

import React, { useState, createContext } from "react";
import useFetchData from './Custom Hooks/useFetchData'

export const Context = createContext();

export function Provider(props) {
  let intialState = {
    track_list: [],
    heading: "",
    loading: true
    // dispatch: action => this.setState(state => reducer(state, action))
  };

  const [state, setState] = useState(intialState)

  // Get Top 10 Tracks
  const url = 'chart.tracks.get?chart_name=top&page=1&page_size=5&country=it&f_has_lyrics=1'
  const [data, loading] = useFetchData(url)
  // setState({ track_list: data, heading: "Top 10 Tracks", loading })  // Causes Too Many Re-renders.
  return (
    <Context.Provider value={[state, setState]}>{props.children}</Context.Provider>
  );
}

useFetchData(自定义挂钩)

import { useState, useEffect } from "react";
import axios from "axios";

function useFetchData(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  console.log('Rendering Again and Again');
  useEffect(() => {
    // Top 10 Tracks
    async function fetchData(url) {
      try {
        const response = await axios.get(
          `${url}&apikey=${process.env.REACT_APP_API_KEY}`
        );
        const data = await response.data.message.body;
        console.log(data);
        setData(data);
        setLoading(false);
      } catch (error) {
        console.log(error);
      }
    }

    fetchData(url);
  }, [url]);

  return [data, loading];
}

export default useFetchData;

浏览器日志

useFetchData.js:7一次又一次渲染

useFetchData.js:7一次又一次渲染

useFetchData.js:16 {track_list:Array(5)}

useFetchData.js:7一次又一次渲染

useFetchData.js:7一次又一次渲染

useFetchData.js:7一次又一次渲染

useFetchData.js:7一次又一次渲染

Error When I uncomment {// setState({ track_list: data, heading: "Top 10 Tracks", loading }) // Causes Too Many Re-renders.} this line in context file

1 个答案:

答案 0 :(得分:3)

setState({ track_list: data, heading: "Top 10 Tracks", loading })导致无限次重新渲染,因为您将其设置在组件主体中,而不是响应某些内容,例如处理程序或效果。因此,每次您设置状态时,都会生成一个渲染,然后重新设置状态,从而导致另一个渲染,即无穷无尽。

在提供者中添加useEffect,以检测对相关数据的更改并在那里设置状态。像

useEffect(() => {
    setState({ track_list: data, heading: "Top 10 Tracks", loading })
}, [loading, data])

仅当loadingdata与上次渲染不同时才会调用此方法。