【问题标题】:why do i get Error: Too many re-renders. React limits the number of renders to prevent an infinite loop为什么我会收到错误:重新渲染太多。 React 限制渲染次数以防止无限循环
【发布时间】:2021-04-15 09:02:12
【问题描述】:

在我从 API 获取的 React.js 代码中,我收到了这个错误 错误:重新渲染过多。 React 限制了渲染的数量以防止无限循环。 请问我做错了什么?

这是我在 App.js 中的 fetch 组件

    const App = () => {
  const [records, setRecords] = useState([])
  const [loading, setLoading] = useState({ loading: false })

  
  useEffect(() => {

    (async function() {
      try {
        setLoading(true)
        const res = await fetch('http://api.enye.tech/v1/challenge/records?limit=20&skip=0')
        const data  = await res.json();
        setRecords({ records: data})
        setLoading(false)
        console.log(data);
  
      } catch (err) {
        console.error(err);
      }
    })()
     
  }, []) 

      if(loading) {
        return <Preloader />
    }
  
    return (
      <Fragment>
        <SearchBar />
        <div className='container'>
          <Records loading={setLoading()} records={setRecords()} />
        </div>
      </Fragment>
    );
  }

这就是我将获取的数据作为道具传递的地方

const Records = ({ records, loading }) => {

    return (
        <div className={styles.p__container}>
        <div className="row">
            <div className="col-sm-8">
                <div className="py-3">
                    {records.length} Records
                </div>
            </div>
        </div>
        <div className={styles.p__grid}>
             {records.map(record => (
                 <RecordItem key={record.id} record={record} />
             ))
            }

        </div>
        <div className={styles.p__footer}>

        </div>
    </div>
    )

我的集成终端没有显示错误,但我在浏览器控制台中收到此错误

我还想看看我是否可以从 API 中仅获取 20 个配置文件而不是 100 个

http://api.enye.tech/v1/challenge/records

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    很可能在这里,当您在每次渲染时调用 setLoading()setRecords 时:

    <Records loading={setLoading()} records={setRecords()} />
    

    您可能只想传递 loadingrecords 变量:

    <Records loading={loading} records={records} />
    

    【讨论】:

      【解决方案2】:

      错误在一行

      <Records loading={setLoading()} records={setRecords()} />
      

      通过编写setLoading()setRecords(),您实际上改变了loadingrecords 的状态。这确保了重新渲染,因为状态正在改变

      我相信,您正在尝试将当前的loading 状态和records 数组作为道具传递给组件记录。为此,您应该传递类似的值

      <Records loading={loading} records={records} />
      

      这应该可以清除 too many re-renders 错误

      useState使用建议

      您初始化状态 loadingsetRecords 的方式与您以后使用的方式不同。

      例如,您将loading 初始化为{loading: false},但稍后调用setLoading(false)。您应该使用

      loading 状态初始化为boolean 状态
      const [loading, setLoading] = useState(false);
      
      // example usage
      setLoading(true);
      

      同样,对于records,您使用空数组useState([]) 进行初始化,但稍后使用setRecords({ records: data})records state 设置为对象

      你应该使用其中一种方法

      /** Approach 1 (Array typed) */
      const [records, setRecords] = useState([]);
      
      // example usage
      setRecords(data);
      
      /** Approach 2 (Object typed) */
      const [records, setRecords] = useState({records: []});
      
      // example usage
      setRecords({records: data});
      

      【讨论】:

        【解决方案3】:

        React 有一个属性,每当 React 组件中的状态值更新时,组件就会重新渲染。在这里,您将 setLoading()setRecords() 作为道具传递给 Records 组件。你应该通过 recordsloading 代替。每次 setLoading()setRecords() 更新时,您的组件都会重新渲染,因此会发生无限循环的重新渲染。

        【讨论】:

          猜你喜欢
          • 2021-05-17
          • 2021-02-04
          • 2021-07-01
          • 2020-08-06
          • 2021-10-21
          • 1970-01-01
          • 2021-02-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多