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 件事
useEffect 是 React 中的最后一个渲染。所以先渲染一个组件,等它完成useEffect 运行.
再读其他代码
useEffect 可能 运行 代码只添加一次 []。例如
useEffect ( () => {
...code
}, [])
此代码将 运行 只执行一次。
- useEffect 可以 运行 代码观察变量,将变量添加到 []。例如
useEffect ( () => {
...code
}, [ count, name , ... ])
此代码将 运行 首次使用,如果计数或名称更改,稍后将 运行
像useEffect这样的钩子用在函数组件中。 Class 组件与 useEffect 的比较是方法 componentDidMount、componentDidUpdate 和 componentWillUnmount。
useEffect 会在组件渲染时 运行,这可能比你想象的要多。
所以useEffect需要第二个参数
第二个参数是一个变量数组,组件将检查这些变量以确保在重新渲染之前已更改。你可以在这里放任何你想要的道具和状态来检查。
在您的情况下,将 [query] 添加为第二段:
useEffect(() => {
fetchResults();
console.log("use effect triggered")
},[query])
要实现这一点,您需要防止 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]);
我正在尝试调用 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 件事
useEffect 是 React 中的最后一个渲染。所以先渲染一个组件,等它完成useEffect 运行.
再读其他代码useEffect 可能 运行 代码只添加一次 []。例如
useEffect ( () => {
...code
}, [])
此代码将 运行 只执行一次。
- useEffect 可以 运行 代码观察变量,将变量添加到 []。例如
useEffect ( () => {
...code
}, [ count, name , ... ])
此代码将 运行 首次使用,如果计数或名称更改,稍后将 运行
像useEffect这样的钩子用在函数组件中。 Class 组件与 useEffect 的比较是方法 componentDidMount、componentDidUpdate 和 componentWillUnmount。
useEffect 会在组件渲染时 运行,这可能比你想象的要多。
所以useEffect需要第二个参数 第二个参数是一个变量数组,组件将检查这些变量以确保在重新渲染之前已更改。你可以在这里放任何你想要的道具和状态来检查。
在您的情况下,将 [query] 添加为第二段:
useEffect(() => {
fetchResults();
console.log("use effect triggered")
},[query])
要实现这一点,您需要防止 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]);