【问题标题】:useEffect causing it to call the method to get posts way too many times. I only want to get the posts when my query changesuseEffect 导致它调用该方法以获取帖子的次数太多。我只想在查询更改时获取帖子
【发布时间】:2021-10-24 05:58:47
【问题描述】:

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

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;

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

【问题讨论】:

标签: javascript reactjs redux use-effect reddit


【解决方案1】:

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

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

  1. useEffect 是 react 中的最后一个渲染。所以首先渲染一个组件并在完成 useEffect 运行时读取其他代码。

  2. useEffect 可能只运行一次添加 [] 的代码。例如

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

此代码将只运行一次。

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

此代码将在第一次运行,稍后将在计数或名称更改时运行

【讨论】:

    【解决方案2】:

    函数组件中使用了 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/

    【讨论】:

      【解决方案3】:

      要实现这一点,您需要防止在任何更改时调用 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]);
      

      【讨论】:

        猜你喜欢
        • 2012-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-07
        • 2021-04-01
        • 1970-01-01
        相关资源
        最近更新 更多