useEffect 导致它多次调用该方法来获取帖子。我只想在查询更改时获取帖子

useEffect causing it to call the method to get posts way too many times. I only want to get the posts when my query changes

我正在尝试调用 reddit API。 post 标题正在显示,但我希望它们在我的查询更改时重新呈现。我只想知道当我的状态发生变化时(也就是我的查询)如何调用方法。我正在使用 react 中的 useEffect 来执行此操作,但每当组件发生任何变化时都会调用它,导致它多次调用该方法以获取 posts 方法。我只想在查询更改时获取 posts。

import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';

function Results()
{   
    const query = useSelector(state => state.query);
    const results = useSelector(state => state.results);

    const dispatch = useDispatch();
    let fetchResults = () =>
    {
        let postTitles = [];
        let postSrcs = [];

        fetch('https://www.reddit.com/r/' + query + '.json')
        .then(response => response.json())
        .then(body => {
            for (let i = 0; i < body.data.children.length; ++i) {
                if (body.data.children[i].data.post_hint === 'image')
                {
                    let img_url = body.data.children[i].data.url_overridden_by_dest;
                    postSrcs.push(img_url);
                }
                let title = body.data.children[i].data.title;
                postTitles.push(title);
            }
            dispatch({type: "QUERY_RESULTS", payload: postTitles})
        }).catch((err) => {
            console.log(err)
        });
    }
    useEffect(() => {
        fetchResults();
        console.log("use effect triggered")
    })
    
  

    return (
        <>
        <h1>Query: {query}</h1>
        
        { !results 
        ? <h1>No Results</h1> 
        : results.map(p => <h6> {p} </h6>)
        }

        </>
    )
}

export default Results;

例如在控制台日志中告诉我何时触发使用效果。当我搜索 post 时,触发的使用效果正在叠加。

useEffect 有不同的模式。具体使用方法可以参考官方文档https://reactjs.org/docs/hooks-reference.html#useeffect

所以你必须知道的主要是 3 件事

  1. useEffect 是 React 中的最后一个渲染。所以先渲染一个组件,等它完成useEffect 运行.

    再读其他代码
  2. useEffect 可能 运行 代码只添加一次 []。例如

useEffect ( () => {
 ...code
}, [])

此代码将 运行 只执行一次。

  1. useEffect 可以 运行 代码观察变量,将变量添加到 []。例如
useEffect ( () => {
 ...code
}, [ count, name , ... ])

此代码将 运行 首次使用,如果计数或名称更改,稍后将 运行

像useEffect这样的钩子用在函数组件中。 Class 组件与 useEffect 的比较是方法 componentDidMount、componentDidUpdate 和 componentWillUnmount。

useEffect 会在组件渲染时 运行,这可能比你想象的要多。

所以useEffect需要第二个参数 第二个参数是一个变量数组,组件将检查这些变量以确保在重新渲染之前已更改。你可以在这里放任何你想要的道具和状态来检查。

在您的情况下,将 [query] 添加为第二段:

 useEffect(() => {
        fetchResults();
        console.log("use effect triggered")
    },[query])

https://css-tricks.com/run-useeffect-only-once/

要实现这一点,您需要防止 useEffect 在任何更改时被调用,并且仅在 query 更改时被调用。

注意:由于您在 fetchResults 中使用 dispatch,因此最好在调用 fetchResults.

之前确保 dispatch 已准备就绪

您的 useEffect 可能如下所示:

useEffect(() => {
  // To prevent call fetchResults if dispatch only is changed
  if (query) {
    fetchResults();
    console.log("use effect triggered");
  }
}, [dispatch, query]);