【问题标题】:Function component keeps rerendering over and over函数组件不断地重新渲染
【发布时间】:2019-08-07 06:16:31
【问题描述】:

我的 react 函数组件不断地重新渲染自己,直到浏览器崩溃。

我能找到的唯一解决方案是在 useEffect() 的末尾输入带有我的常量的 []。

function getNestedObject(nestedObj, pathArr) {
  return pathArr.reduce(
    (obj, key) => (obj && obj[key] !== "undefined" ? obj[key] : undefined),
    nestedObj
  );
}

function Genres() {
  const [genreList, setgenreList] = useState(0);

  useEffect(() => {
    let results = "";
    axios({
      url: "https://api.themoviedb.org/3/genre/movie/list?",
      method: "GET",
      responseType: "json",
      params: {
        api_key: "00000000000",
        language: "en-US"
      }
    }).then(result => (results = result.data.genres));

    let a = [];
    for (let i = 0; i < 10; i++) {
      let name = getNestedObject(results, [i, "name"]);
      a.push(name);
    }
    setgenreList(a);
    console.log(genreList);
  }, [genreList]);
  return <div>test</div>;
}

我也试过没有useEffect,它给出了相同的循环结果。

我在渲染中有&lt;Genres /&gt;

【问题讨论】:

  • results 将是你的 for 循环中的一个空字符串,因为 axios 响应还没有返回,它会抛出任何错误吗? :) 所以它会返回 undefined 作为名字,你的 a 将包含 10 次
  • 是的,我可以修复的 axios get,它目前在 console.log 中打印出空数组。但我的问题是它不断地重新渲染 :(
  • 尝试一个空数组作为第二个参数?
  • 你能说明你在哪里使用这个组件吗?
  • 您是否只希望它在组件安装时运行一次?如果是这样,您需要将第二个参数传递给useEffect(),它应该是一个空数组[]

标签: javascript reactjs react-hooks


【解决方案1】:

它的发生是因为你在打电话

    setgenreList(a);

在 useffect ,genreList 改变它的状态, UseEffect 再次运行

当你写作时

  useEffect(() => {}, [genreList])

那么每次调用它的setter时都会调用它setgenreList

你可以写

useEffect(() => {
    //code here
    }, [])

【讨论】:

    【解决方案2】:

    实际上,您每次都生成一个空数组并使用新生成的数组更新状态,因此 useEffect 无限循环(检查 [] === [])。此外,您在代码中有一个明显的错误:状态更新根本不依赖于 axios 结果,因为您不等待响应结果(“then”块在 setgenreList(a) 之后执行)。在“then”函数中使用状态更新。

    【讨论】:

      【解决方案3】:

      我想我会添加一个执行类似实现的小答案,以及如何根据当前实现(基于Rules of Hooks)至少处理条件

      一方面,您似乎完全按照文档进行操作,当您调用useState 时,您为其提供了默认值,并将其设置为0,它应该是一个空数组(因为之后你用它填充一个数组)

      对于useEffect,您不需要将第二个参数作为空数组(尽管这表明效果永远不应重新运行),您也可以将其留空,但您可以验证您的数组是否已经有值它,如果没有,你可以进行网络调用(你使用,但为了简单起见,我使用原生的fetch

      const { useState, useEffect } = React;
      
      const container = document.querySelector('#container');
      
      const BreedList = () => {
        const [breeds, setBreeds] = useState([]);
        
        useEffect( () => {
          if (!breeds.length) {
            fetch( 'https://dog.ceo/api/breeds/list/all' )
              .then( resp => resp.json() )
              .then( result => {
                setBreeds( Object.keys( result.message ) );
              } );
          }
        }, [breeds] );
        
        return (
          <div>
            <h1>Breeds</h1>
            { breeds.map( breed => <div key={ breed }>{ breed }</div> ) }
          </div>
        );
      };
      
      ReactDOM.render( <BreedList />, container );
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
      <div id="container"></div>

      【讨论】:

        猜你喜欢
        • 2022-01-27
        • 2018-08-12
        • 2023-01-30
        • 1970-01-01
        • 2020-02-13
        • 1970-01-01
        • 2019-06-01
        • 2019-01-01
        • 2021-07-25
        相关资源
        最近更新 更多