reactjs - useEffect 导致无限循环
问题描述
我得到一个无限循环,它不断地从 API 中获取信息。
如果我将 fetchTheMovie() 包装在 if 语句中,问题可以解决,但我不明白原因、任何想法或更好的解决方案?
if (!movie.Title) {
fetchTheMovie(id);
}
端点是 /movie/id
电影组件:
const SingleMovie = (props) => {
const { id } = useParams();
const {movie} = props;
useEffect(() => {
const {fetchTheMovie} = props;
fetchTheMovie(id);
}, []);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(WithSpinner(SingleMovie));
WithSpinner 组件:
const WithSpinner = (WrappedComponent) => {
const Spinner = ({ isLoading, ...otherProps }) => {
return isLoading ? (
<SpinnerOverlay>
<SpinnerContainer />
</SpinnerOverlay>
) : (
<WrappedComponent {...otherProps} />
);
};
return Spinner;
};
使用该组件的页面
const Page = ({ loading }) => {
const { id } = useParams();
return (
<div>
<SingleMovieComp isLoading={loading} />
</div>
);
};
行动:
export function fetchMovieStart() {
return {
type: SingleMovieActionTypes.FETCH_MOVIE_START,
};
}
export function fetchMovieSuccess(movie) {
return {
type: SingleMovieActionTypes.FETCH_MOVIE_SUCCESS,
payload: movie,
};
}
export function fetchMovieError(error) {
return {
type: SingleMovieActionTypes.FETCH_MOVIE_ERROR,
payload: error,
};
}
export const fetchMovieAsync = (movieId) => {
return (dispatch) => {
dispatch(fetchMovieStart());
fetch(`URL`)
.then((response) => response.json())
.then((movie) => dispatch(fetchMovieSuccess(movie)))
.catch((error) => dispatch(fetchMovieError(error.message)));
};
};
减速器:
const INITIAL_STATE = {
loading: false,
movie: {},
};
const singleMovieReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case SingleMovieActionTypes.FETCH_MOVIE_START: {
return {
...state,
movie: {},
loading: true,
};
}
case SingleMovieActionTypes.FETCH_MOVIE_SUCCESS: {
return {
...state,
movie: action.payload,
loading: false,
};
}
case SingleMovieActionTypes.FETCH_MOVIE_ERROR: {
return {
...state,
loading: false,
};
}
default:
return state;
}
};
解决方案
您可以尝试以下方法:
const ComponentWithSpinner = WithSpinner(SingleMovie);
//create single movie container
const SingleMovieContainer = (props) => {
const { id } = useParams();
const { fetchTheMovie } = props;
//remove the useEffect from SingleMovie
useEffect(() => {
fetchTheMovie(id);
//you need to add these dependencies
}, [fetchTheMovie, id]);
//Here you could try to use useSelector to get the movie
// and pass to SingleMovie but I think you already do
// that somewhere else
//return component with spinner so SingleMovieContainer
// will not unmount when you load movie
return <ComponentWithSpinner {...props} />;
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(SingleMovieContainer);
问题是 SingleMovie 在您加载电影时被卸载,并且在加载为假时被安装,这导致加载设置为 true(已调度 fetchMovie),因此它再次被卸载。
推荐阅读
- c++ - Qt 6.1 QSGTexture 的纹理数据可以动态更改吗?
- javascript - 计算对象数组的中位数
- visual-studio-code - 无法在编辑器中输入数字“1”
- r - 在 R 闪亮中按下浏览按钮后自动呈现“textInput”
- flutter - path_provider getExternalStorageDirectories() 只返回一个目录
- r - ggplot2 R 图表
- c# - MySql 数据库中的数据未显示在 datagridview Windows 窗体中,C#
- python - 装满字典的熊猫专栏
- python - 从源数据训练 Word2Vec 模型 - 问题标记化数据
- testing - 登录后重定向逻辑不适用于 TestCafe 角色