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