[英]useEffect is causing an infinite Loop
I am getting an infinite loop and it is constantly fetching information from the API.我得到一个无限循环,它不断从 API 获取信息。
The issue can be solved if I wrap fetchTheMovie() inside an if statement but I do not understand the reason, any ideas or any better solution?如果我将 fetchTheMovie() 包装在 if 语句中,问题可以解决,但我不明白原因、任何想法或任何更好的解决方案?
if (!movie.Title) {
fetchTheMovie(id);
}
The endpoint is /movie/id端点是 /movie/id
Movie Component:电影组件:
const SingleMovie = (props) => {
const { id } = useParams();
const {movie} = props;
useEffect(() => {
const {fetchTheMovie} = props;
fetchTheMovie(id);
}, []);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(WithSpinner(SingleMovie));
WithSpinner Component : WithSpinner 组件:
const WithSpinner = (WrappedComponent) => {
const Spinner = ({ isLoading, ...otherProps }) => {
return isLoading ? (
<SpinnerOverlay>
<SpinnerContainer />
</SpinnerOverlay>
) : (
<WrappedComponent {...otherProps} />
);
};
return Spinner;
};
Page that the component is used使用该组件的页面
const Page = ({ loading }) => {
const { id } = useParams();
return (
<div>
<SingleMovieComp isLoading={loading} />
</div>
);
};
Action:行动:
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)));
};
};
Reducer:减速器:
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;
}
};
You can try the following:您可以尝试以下方法:
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);
Problem is that SingleMovie is unmounted when you load a movie and gets mounted when loading is false, that causes loading to be set true (fetchMovie is dispatched) so it is unmounted again.问题是 SingleMovie 在您加载电影时被卸载,并且在加载为假时被安装,这导致加载设置为 true(已调度 fetchMovie),因此它再次被卸载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.