【问题标题】:Too many re-renders. React limits the number of renders to prevent an infinite loop - why?太多的重新渲染。 React 限制了渲染的数量以防止无限循环 - 为什么?
【发布时间】:2021-06-24 00:25:27
【问题描述】:

我正在尝试使用 Wikipedia API 将搜索结果分类。

这是我的Search 组件:

function Search() {
    const [value, setValue] = useState("");
    const [results, setResults] = useState([]);

    useEffect(() => {
        let timerId = null;
        if (value) {
            timerId = setTimeout(async () => {
                const { data } = await axios.get(
                    "https://en.wikipedia.org/w/api.php",
                    {
                        params: {
                            action: "query",
                            list: "search",
                            origin: "*",
                            format: "json",
                            srsearch: value,
                        },
                    }
                );
                console.log(data);
                setResults(data.query.search);
            }, 400  );
        }
        return () => {
            clearTimeout(timerId);
        };
    }, [value]);
    return (
        <>
            <form className="ui form">
                <input
                    type="text"
                    placeholder="Search Wikipedia..."
                    value={value}
                    onChange={(e) => setValue(e.target.value)}
                ></input>
            </form>
            <List results={results} />
        </>
    );
}

有一种增量搜索可以解释 setTimeout。

这是我的List 组件:

const List = ({ results }) => {
    const [category, setCategory] = useState("");

    const renderedList = results.map((item) => {
        if (item.snippet.includes("film") || item.snippet.includes("movie")) {
            console.log("movie", item);
        }
        if (
            item.snippet.includes("band") ||
            item.snippet.includes("musician")
        ) {
            setCategory("music");
        }
        return (
            <div className="ui segment">
                <h2>
                    <a
                        href={"https://en.wikipedia.org?curid=" + item.pageid}
                        className="header"
                        target="_blank"
                        rel="noopener noreferrer"
                    >
                        {item.title}
                    </a>
                </h2>
                <p dangerouslySetInnerHTML={{ __html: item.snippet }}></p>
                <p>{category}</p>
            </div>
        );
    });

我尝试将超时设置得更高,以便在输入完整的搜索词之前没有任何活动的重新渲染,但这会得到相同的结果。 API 也只返回一个包含 10 个结果的数组,因此它不会处理大量数据。

App.js 只包含List,所以我不明白为什么会有任何问题。

任何帮助表示赞赏 - 在此先感谢!

【问题讨论】:

  • 别介意我问你为什么还要从 setTimeout 调用你的 API?不确定您是出于某种实践原因还是不了解 useEffect 的目的,但基本上在 useEffect 内部,您应该像 axios.get(..).then(response => setResults(response. data)) - 不需要在钩子主体中使用 async/await(即使 async/await 很好)但是超时真的很尴尬..
  • 非常不了解useEffect,我在学习react的早期阶段。我会研究你的建议。感谢您的帮助!
  • 啊,好吧,所以你绝对不需要那个超时时间——因为你的状态改变会重新渲染你的组件,并且你在 axios 调用完成后设置你的状态——所以你不需要思考“程序上”但“反应性”。
  • 您完全正确地认为 timout 是不必要的,再次感谢您的帮助 Ognjen。出于我的目的,我发现将结果推送到数组而不是单独类别上的 setState 就足够了。
  • 不客气,我已经写了一个答案,以便将来可以帮助其他人。保重!

标签: javascript reactjs state wikipedia-api


【解决方案1】:

正如我们在 cmets 中讨论的那样,您提到您是 React 的初学者,没有必要在设置超时的情况下调用 axios,因为 axios 返回一个承诺,然后一旦承诺得到解决,您就更新您的状态,并更新您的state 会重新渲染你的组件。

【讨论】:

    猜你喜欢
    • 2021-01-22
    • 2022-01-14
    • 2020-09-22
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多