加载指示器出现但在 react-redux 中不移动
Loading indicator appears but does not move in react-redux
import { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { BiLeftArrow, BiRightArrow } from "react-icons/bi";
import { useHistory } from "react-router-dom";
import {
fetchMovies,
handleCurrentPage,
handleStatus,
} from "../../feautures/movies/moviesSlice";
import Card from "../Card/Card";
import Slider from "../UI/Slider/Slider";
import Navigation from "../Navigations/Navigation";
import "./MoviesList.scss";
import requests from "../../requests";
import LoadingIndicator from "../UI/LoadingIndicator/LoadingIndicator";
const MoviesList = () => {
const dispatch = useDispatch();
// Handle movies states
const moviesStatus = useSelector((state) => state.movies.status);
const moviesState = useSelector((state) => state.movies.movies);
const moviesError = useSelector((state) => state.movies.error);
const moviesHeading = useSelector((state) => state.movies.moviesHeading); // It's for pagination
const moviesCurrentPage = useSelector((state) => state.movies.currentPage);
let history = useHistory();
// Handle header input
const inputValue = useSelector((state) => state.movies.inputValue);
// Movies according input values
const filteredMovie = moviesState.filter((movie) =>
movie.original_title.toLowerCase().includes(inputValue)
);
// Handle page number
const handlePageNumber = (nexPage) => {
dispatch(handleStatus("idle"));
dispatch(
handleCurrentPage(Math.max(1, Math.min(moviesCurrentPage + nexPage, 10)))
);
};
// Handle pagination
useEffect(() => {
if (moviesStatus === "idle") {
if (moviesHeading === "POPULAR") {
dispatch(fetchMovies(requests.fetchPopular(moviesCurrentPage)));
} else if (moviesHeading === "NOW PLAYING") {
dispatch(fetchMovies(requests.fetchNowPlaying(moviesCurrentPage)));
} else if (moviesHeading === "UP COMING") {
dispatch(fetchMovies(requests.fetchUpComing(moviesCurrentPage)));
}
}
}, [moviesCurrentPage, dispatch, moviesHeading, moviesStatus]);
let content;
if (moviesStatus === "loading") {
} else if (moviesStatus === "succeeded") {
content = (
<div className="movies__container">
<BiLeftArrow
className="movies__arrow movies__arrow--left"
onClick={() => {
handlePageNumber(-1);
history.push(
`/page/${(() =>
Math.max(1, Math.min(moviesCurrentPage - 1, 10)))()}`
);
}}
/>
{filteredMovie.map((movie) => {
return <Card movie={movie} key={movie.id} />;
})}
<BiRightArrow
className="movies__arrow movies__arrow--right"
onClick={() => {
handlePageNumber(1);
history.push(
`/page/${(() =>
Math.max(1, Math.min(moviesCurrentPage + 1, 10)))()}`
);
}}
/>
</div>
);
} else if (moviesStatus === "failed") {
content = <div>{moviesError}</div>;
}
return (
<div className="movies">
<Slider />
<Navigation />
{moviesStatus === "loading" ? <LoadingIndicator /> : content}
</div>
);
};
export default MoviesList;
LoadingIndicator.jsx
import "./LoadingIndicator.scss"
const LoadingIndicator = () => {
return (
<div className="loading">
<div className="loading__circle"></div>
<div className="loading__circle"></div>
<div className="loading__circle"></div>
</div>
);
};
export default LoadingIndicator;
LoadingIndicator.scss
.loading {
display: flex;
justify-content: space-between;
align-self: center;
width: 480px;
&__circle {
width: 150px;
height: 150px;
border-radius: 50%;
background: linear-gradient(
45deg,
rgba(2, 0, 36, 1) 0%,
rgba(9, 9, 121, 1) 35%,
rgba(0, 212, 255, 1) 100%
);
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.3);
transform: translateX(0);
z-index: 2;
&:nth-child(1) {
animation: move-1 2s infinite;
}
&:nth-child(3) {
animation: move-3 2s infinite;
}
}
}
@keyframes move-1 {
0% {
z-index: 3;
transform: translateX(0);
}
25% {
z-index: 3;
transform: translateX(80px);
}
50% {
z-index: 3;
transform: translateX(0);
}
50.1% {
z-index: 1;
transform: translateX(0);
}
75% {
z-index: 1;
transform: translateX(80px);
}
100% {
z-index: 1;
transform: translateX(0);
}
}
@keyframes move-3 {
0% {
z-index: 1;
transform: translateX(0);
}
25% {
z-index: 1;
transform: translateX(-80px);
}
50% {
z-index: 1;
transform: translateX(0);
}
50.1% {
z-index: 3;
transform: translateX(0);
}
75% {
z-index: 3;
transform: translateX(-80px);
}
100% {
z-index: 3;
transform: translateX(0);
}
}
嗨 all.I 尝试在 moviesStatus === "loading"
时显示 <LoadingIndicator />
组件直到 moviesStatus === "succeeded"
但问题是 <LoadingIndicator />
组件出现但没有移动,如您所见演示(三个蓝色的大球)。我在这个文档中确实做了同样的事情(https://codesandbox.io/s/github/reduxjs/redux-essentials-example-app/tree/checkpoint-3-postRequests/?from-embed=&file=/src/features/posts/PostsList.js)但是 work.I 几天都没有解决问题。
演示:https://hope-movie.web.app/page/1
回购:https://github.com/UmutPalabiyik/hope-movie-app
您很快就收到了服务器的响应,所以您看不到 LoadingIndicator。要查看 LoadingIndicator,您可以手动降低响应速度。您可以像这样更新 fetchMovies
函数:
export const fetchMovies = createAsyncThunk("movies/fetch", async (arg) => {
return await new Promise((resolve) => {
setTimeout(async () => {
console.log("url: ", arg);
const response = await axios.get(arg);
resolve(response.data.results);
}, 3000);
});
});
import { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { BiLeftArrow, BiRightArrow } from "react-icons/bi";
import { useHistory } from "react-router-dom";
import {
fetchMovies,
handleCurrentPage,
handleStatus,
} from "../../feautures/movies/moviesSlice";
import Card from "../Card/Card";
import Slider from "../UI/Slider/Slider";
import Navigation from "../Navigations/Navigation";
import "./MoviesList.scss";
import requests from "../../requests";
import LoadingIndicator from "../UI/LoadingIndicator/LoadingIndicator";
const MoviesList = () => {
const dispatch = useDispatch();
// Handle movies states
const moviesStatus = useSelector((state) => state.movies.status);
const moviesState = useSelector((state) => state.movies.movies);
const moviesError = useSelector((state) => state.movies.error);
const moviesHeading = useSelector((state) => state.movies.moviesHeading); // It's for pagination
const moviesCurrentPage = useSelector((state) => state.movies.currentPage);
let history = useHistory();
// Handle header input
const inputValue = useSelector((state) => state.movies.inputValue);
// Movies according input values
const filteredMovie = moviesState.filter((movie) =>
movie.original_title.toLowerCase().includes(inputValue)
);
// Handle page number
const handlePageNumber = (nexPage) => {
dispatch(handleStatus("idle"));
dispatch(
handleCurrentPage(Math.max(1, Math.min(moviesCurrentPage + nexPage, 10)))
);
};
// Handle pagination
useEffect(() => {
if (moviesStatus === "idle") {
if (moviesHeading === "POPULAR") {
dispatch(fetchMovies(requests.fetchPopular(moviesCurrentPage)));
} else if (moviesHeading === "NOW PLAYING") {
dispatch(fetchMovies(requests.fetchNowPlaying(moviesCurrentPage)));
} else if (moviesHeading === "UP COMING") {
dispatch(fetchMovies(requests.fetchUpComing(moviesCurrentPage)));
}
}
}, [moviesCurrentPage, dispatch, moviesHeading, moviesStatus]);
let content;
if (moviesStatus === "loading") {
} else if (moviesStatus === "succeeded") {
content = (
<div className="movies__container">
<BiLeftArrow
className="movies__arrow movies__arrow--left"
onClick={() => {
handlePageNumber(-1);
history.push(
`/page/${(() =>
Math.max(1, Math.min(moviesCurrentPage - 1, 10)))()}`
);
}}
/>
{filteredMovie.map((movie) => {
return <Card movie={movie} key={movie.id} />;
})}
<BiRightArrow
className="movies__arrow movies__arrow--right"
onClick={() => {
handlePageNumber(1);
history.push(
`/page/${(() =>
Math.max(1, Math.min(moviesCurrentPage + 1, 10)))()}`
);
}}
/>
</div>
);
} else if (moviesStatus === "failed") {
content = <div>{moviesError}</div>;
}
return (
<div className="movies">
<Slider />
<Navigation />
{moviesStatus === "loading" ? <LoadingIndicator /> : content}
</div>
);
};
export default MoviesList;
LoadingIndicator.jsx
import "./LoadingIndicator.scss"
const LoadingIndicator = () => {
return (
<div className="loading">
<div className="loading__circle"></div>
<div className="loading__circle"></div>
<div className="loading__circle"></div>
</div>
);
};
export default LoadingIndicator;
LoadingIndicator.scss
.loading {
display: flex;
justify-content: space-between;
align-self: center;
width: 480px;
&__circle {
width: 150px;
height: 150px;
border-radius: 50%;
background: linear-gradient(
45deg,
rgba(2, 0, 36, 1) 0%,
rgba(9, 9, 121, 1) 35%,
rgba(0, 212, 255, 1) 100%
);
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.3);
transform: translateX(0);
z-index: 2;
&:nth-child(1) {
animation: move-1 2s infinite;
}
&:nth-child(3) {
animation: move-3 2s infinite;
}
}
}
@keyframes move-1 {
0% {
z-index: 3;
transform: translateX(0);
}
25% {
z-index: 3;
transform: translateX(80px);
}
50% {
z-index: 3;
transform: translateX(0);
}
50.1% {
z-index: 1;
transform: translateX(0);
}
75% {
z-index: 1;
transform: translateX(80px);
}
100% {
z-index: 1;
transform: translateX(0);
}
}
@keyframes move-3 {
0% {
z-index: 1;
transform: translateX(0);
}
25% {
z-index: 1;
transform: translateX(-80px);
}
50% {
z-index: 1;
transform: translateX(0);
}
50.1% {
z-index: 3;
transform: translateX(0);
}
75% {
z-index: 3;
transform: translateX(-80px);
}
100% {
z-index: 3;
transform: translateX(0);
}
}
嗨 all.I 尝试在 moviesStatus === "loading"
时显示 <LoadingIndicator />
组件直到 moviesStatus === "succeeded"
但问题是 <LoadingIndicator />
组件出现但没有移动,如您所见演示(三个蓝色的大球)。我在这个文档中确实做了同样的事情(https://codesandbox.io/s/github/reduxjs/redux-essentials-example-app/tree/checkpoint-3-postRequests/?from-embed=&file=/src/features/posts/PostsList.js)但是 work.I 几天都没有解决问题。
演示:https://hope-movie.web.app/page/1 回购:https://github.com/UmutPalabiyik/hope-movie-app
您很快就收到了服务器的响应,所以您看不到 LoadingIndicator。要查看 LoadingIndicator,您可以手动降低响应速度。您可以像这样更新 fetchMovies
函数:
export const fetchMovies = createAsyncThunk("movies/fetch", async (arg) => {
return await new Promise((resolve) => {
setTimeout(async () => {
console.log("url: ", arg);
const response = await axios.get(arg);
resolve(response.data.results);
}, 3000);
});
});