如何解决我可以做些什么来改变状态而不重新渲染
import { useEffect,useState } from "react";
import { useSelector,usedispatch } from "react-redux";
import { fetchMovies } from "../../feautures/movies/moviesSlice";
import { BiLeftArrow,BiRightArrow } from "react-icons/bi";
import Card from "../Card/Card";
import Slider from "../UI/Slider/Slider";
import Navigation from "../Navigations/Navigation";
import "./MoviesList.scss";
import request from "../../requests";
const MoviesList = () => {
const dispatch = usedispatch();
// Current Page
const [currentPage,setCurrentPage] = useState(1);
// 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
// Handle header input
const inputValue = useSelector((state) => state.movies.inputValue);
// Handle movies heading
const moviesMoviesheading = useSelector(
(state) => state.movies.moviesheading
);
// Movies according input values
const filteredMovie = moviesstate.filter((movie) =>
movie.original_title.toLowerCase().includes(inputValue)
);
// Handle Page Number
const handlePageNumber = (rotation) => {
if (rotation === "goPrev" && currentPage >= 2) {
setCurrentPage((prev) => prev - 1);
console.log("current page: ",currentPage);
} else if (rotation === "goNext" && currentPage < 10) {
setCurrentPage((prev) => prev + 1);
console.log("current page: ",currentPage);
}
};
// Handle Pagination
const prevNextPage = () => {
if (moviesheading === "POPULAR") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchPopular(currentPage)));
} else if (moviesheading === "Now PLAYING") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchPopular(currentPage)));
} else if (moviesheading === "UP COMING") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchUpComing(currentPage)));
}
};
useEffect(() => {
if (moviesstatus === "idle") {
dispatch(fetchMovies(request.fetchPopular()));
}
},[dispatch,moviesstatus]);
let content;
if (moviesstatus === "loading") {
<div>selamlar</div>;
} else if (moviesstatus === "succeeced") {
content = (
<div className="movies__container">
<BiLeftArrow
className="movies__arrow movies__arrow--left"
onClick={() => {
handlePageNumber("goPrev")
prevNextPage()
}}
/>
{filteredMovie.map((movie) => {
return <Card movie={movie} key={movie.id} />;
})}
<BiRightArrow
className="movies__arrow movies__arrow--right"
onClick={() => {
handlePageNumber("goNext")
prevNextPage()
}}
/>
</div>
);
} else if (moviesstatus === "Failed") {
content = <div>{moviesError}</div>;
}
return (
<div className="movies">
<Slider />
<div className="movies__heading">{moviesMoviesheading}</div>
<Navigation />
{content}
</div>
);
};
export default MoviesList;
大家好,今天好。我尝试用 react-redux 制作电影网站。但我卡在某个地方。当我点击向右箭头按钮 handlePageNumber
函数增加 currentPage 然后我将此值传递给 {{1 }} 转到下一页。但是当我单击向右箭头按钮时,dispatch(fetchMovies(request.fetchPopular(currentPage)))
状态仍然有 1 个值。如果再单击一次 currentPage
有 2 个值。为什么它没有值2 当我第一次点击它?我猜重新渲染后值会发生变化,如果可以,我该怎么办?最后,如果我的代码中有什么不好的地方,如果你能告诉我如何让代码干净利落,我将不胜感激。
解决方法
问题
问题是 React 状态更新是异步处理的,所以在下一行调用 handlePageNumber("goPrev")
时,handlePageNumber("goNext")
或 prevNextPage()
中排队的状态更新尚未处理,所以currentPage
仍然是当前渲染周期的值。
请参阅此 SO answer(useState set 方法不会立即反映更改)以获取说明。
解决方案
您可以从依赖于 prevNextPage()
的 useEffect
调用 currentPage
函数。由于 prevNextPage
未在其他地方调用,您可以在 useEffect
回调中定义它并调用它,或者只是将旧逻辑移到useEffect
回调的主体。您还需要包含 moviesHeading
作为依赖项。
useEffect(() => {
if (moviesHeading === "POPULAR") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchPopular(currentPage)));
} else if (moviesHeading === "NOW PLAYING") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchPopular(currentPage)));
} else if (moviesHeading === "UP COMING") {
console.log("current page",currentPage)
dispatch(fetchMovies(request.fetchUpComing(currentPage)));
}
},[currentPage,dispatch,moviesHeading]);
并从点击处理程序中删除调用。
content = (
<div className="movies__container">
<BiLeftArrow
className="movies__arrow movies__arrow--left"
onClick={() => {
handlePageNumber("goPrev");
}}
/>
{filteredMovie.map((movie) => {
return <Card movie={movie} key={movie.id} />;
})}
<BiRightArrow
className="movies__arrow movies__arrow--right"
onClick={() => {
handlePageNumber("goNext");
}}
/>
</div>
我可能还建议简化您的 handlePageNumber
逻辑以使用数字值而不是字符串,并将该值限制在您的页面范围内
// Handle Page Number
const handlePageNumber = (nextPage) => {
setCurrentPage(page => Math.max(1,Math.min(page + nextPage,10));
};
在回调中添加 pass 1
或 -1
以返回页面或前进到下一页。
content = (
<div className="movies__container">
<BiLeftArrow
className="movies__arrow movies__arrow--left"
onClick={() => {
handlePageNumber(-1);
}}
/>
{filteredMovie.map((movie) => {
return <Card movie={movie} key={movie.id} />;
})}
<BiRightArrow
className="movies__arrow movies__arrow--right"
onClick={() => {
handlePageNumber(1);
}}
/>
</div>
,
似乎 react 的 setState 方法是异步工作的,但您认为它是同步方法。 如果我是你,我会将 pagenumber 存储在 redux 状态。我编写操作来处理单击上一个/下一个按钮并发送下一页状态(如果 currentPage = 8,则我为 nextButton 发送 9,为 prevButton 发送 7),触发此操作后,我使用 redux-thunk 或 redux- 处理异步操作saga,每当我从中间件得到响应时,我都会为此异步操作调用成功或失败操作,它将处理下一个 redux 状态
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。