繁体   English   中英

反应组件循环

[英]React-component loops

有一个反应组件:

import React, { useState, useCallback } from 'react';
import { useHttp } from '../../hooks/http.hooks';

function Main() {
    const {loading, error, request} = useHttp();
    const [news, setNews] = useState(0);

    const topNews = useCallback(async function() {
        const data = await request('http://localhost:5500/api/news/top/2');
        return data;
    }, []);

    console.log(topNews());

    return (
        <div>Hello world</div>
    );
}

export default Main;

和一个自定义挂钩:

import { useState } from 'react';

export const useHttp = () => {
    const [loading, setLoading] = useState();
    const [error, setError] = useState();
    async function request(url, { method = 'GET', body = null, headers = {} } = {}) {
        setLoading(true);
        try {
            const response = await fetch(url, { method, body, headers });
            const data = await response.json();

            if (!response.ok) {
                throw new Error(data.msg || 'unhandled error');
            }

            return data;
        } catch (err) {
            setError(err);
        } finally {
            setLoading(false);
        }
    }

    return { loading, request, error }
}

启动它会抛出错误:

错误:重新渲染太多。 React 限制渲染次数以防止无限循环。

控制台中有这么多 Promise:

在此处输入图像描述

据我了解,当loading发生变化时, Main正在渲染,因为我添加了一个useCallback()但它不起作用。 如何摆脱循环的权利?

在你的 React 组件中, request应该在useEffect而不是useCallback中调用。 如果你保持这种方式,循环看起来像这样:

  1. 组件渲染
  2. request被调用
  3. request更新组件状态
  4. 状态改变强制渲染,所以 go 回到项目符号 #2

您应该将代码更改为如下所示:

import React, { useState, useEffect } from 'react';
import { useHttp } from '../../hooks/http.hooks';

function Main() {
    const {loading, error, request} = useHttp();
    const [news, setNews] = useState([]);

    useEffect(() => {
      const data = await request('http://localhost:5500/api/news/top/2');
      setNews(data);
    }, [])

    console.log(news);

    return (
        <div>Hello world</div>
    );
}

export default Main;

有关详细信息和高级用法,请参阅useEffect

将异步 function 调用移动到useEffect ,您当前在每个渲染器上调用它:

function Main() {
    const {loading, error, request} = useHttp();
    const [news, setNews] = useState(0);


    useEffect(() => {
      async function topNews() {
        const data = await request('http://localhost:5500/api/news/top/2');
        return data;
    }
      setNews(topNews());
    }, [])

    return (
        <div>{JSON.stringify(news,null,2)}</div>
    );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM