微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以做些什么来改变状态而不重新渲染

如何解决我可以做些什么来改变状态而不重新渲染

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 answeruseState 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?