Redux:为什么我的useEffect()在每一个页面上都不断地重报它的值



我正在学习react-redux。我遇到了以下问题:

  1. 我进行了两次异步api调用(使用redux-thunk(:
  • 第一个获取国家名称的对象(在一个对象中,例如:{countries: [{...}, ...]}
  1. 我后来用这些国家名称进行第二次api调用,以获取这些国家的所有足球联赛(有时没有,所以我得到了null(。在这种情况下,分别使用每个countryName进行调用。我把结果做成一个数组
  2. 这个数组长度为255m,我过滤掉其中的null值并映射联赛名称
  3. 在我点击一个联盟的名称后,会呈现一个页面({Link} from "react-router-dom";(。现在我的问题出现了
  4. 当我单击以返回主页(<Link to={"/"} >(时,两个useEffect()都在再次进行api调用。为什么

这是我的useEffect():的代码

const dispatch = useDispatch();
const selectAllCountries = useSelector(state => state.allCountries);
const selectAllLeagues = useSelector(state => state.allLeagues);
useEffect(() => {
dispatch(allCountries());
}, [dispatch]);
useEffect(() => {
if(!_.isEmpty(selectAllCountries.data)) {
selectAllCountries.data.countries.map(el => dispatch(allLeagues(el.name_en)));
}
}, [dispatch, selectAllCountries.data]);

我试着制作一个自定义挂钩,并将useEffect()放在那里:

const useCountries = getCountries => {useEffect(() => {
dispatch(getCountries());
},[getCountries])}
useCountries(allCountries);

如这里所建议的:React挂钩:useEffect 的调度操作

但这无济于事。

需要任何帮助都会很好。


答案:

在"中/操作//allLeagues.js

...
import _ from "lodash";
export const allLeagues = (country) => async (dispatch, getState) => {
if (!_.isEmpty(getState().allLeagues) && !_.isEmpty(getState().allLeagues.data)) {
return Promise.resolve();
} else {
try {
...

}
}    
}

问题,这也很有帮助:从存储中获取数据(如果存在(或在React中调用API(看看关于getStore()的答案(

正如上面的评论中所提到的,当您单击转到新页面时,主页将卸载。当您返回时,页面重新安装,效果再次运行,触发另一个API调用。您可以通过检查存储中是否已经存在值来阻止API调用。我个人喜欢在动作创作者中这样做,但你也可以在效果中这样做。

正在检查操作创建者中的状态:

function allLeagues(countryName) {
return (dispatch, getState) => {
// Call `getState` and check whether `allLeagues` has been populated yet.
const { allLeagues } = getState();
if (allLeagues && allLeagues.data && allLeagues.data.length) {
// You already have the data, no need to make the API call.
return Promise.resolve();
}
// No data, make the API call...
};
}

检查效果中的状态:

useEffect(() => {
// Check whether the league data is set or not.
if(!_.isEmpty(selectAllCountries.data) && _.isEmpty(selectAllLeagues.data)) {
selectAllCountries.data.countries.map(el => dispatch(allLeagues(el.name_en)));
}
}, [dispatch, selectAllCountries.data, selectAllLeagues.data]);

相关内容

  • 没有找到相关文章

最新更新