Javascript 每次渲染子组件时都会分派操作

Javascript 每次渲染子组件时都会分派操作,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我是一个新的反应者,并尝试使用钩子,我陷入了一个问题,我正在使用useEffect向redux商店发送一个动作。所以一切都很好,但我面临的问题是,每次我在主组件中呈现子组件时,它都会分派动作。就像有基本上是子组件的卡片一样,每当我点击其中的一个以显示更多细节时,如果我关闭组件,它会分派父组件中的操作,因此我的问题是如何防止这种情况发生,并且只渲染一次项。如果您需要任何其他代码,请告诉我 父组件 import React, { useEffect } from "react";

我是一个新的反应者,并尝试使用钩子,我陷入了一个问题,我正在使用useEffect向redux商店发送一个动作。所以一切都很好,但我面临的问题是,每次我在主组件中呈现子组件时,它都会分派动作。就像有基本上是子组件的卡片一样,每当我点击其中的一个以显示更多细节时,如果我关闭组件,它会分派父组件中的操作,因此我的问题是如何防止这种情况发生,并且只渲染一次项。如果您需要任何其他代码,请告诉我

父组件

import React, { useEffect } from "react";
//ANIMATION AND STYLED
import styled from "styled-components";
import { motion, AnimatePresence, AnimateSharedLayout } from "framer-motion";

//REDUX and ROUTER
import {
  AllPopularGame,
  NextPage,
  PrevPage,
} from "../Actions/popularGameActions";
import { useSelector, useDispatch } from "react-redux";
import { Link, useLocation, useHistory } from "react-router-dom";
//COMPONENTS
import Game from "./games";
import GameDetail from "./gameDetail";

const PopularGames = () => {
  //GETTNG PATH
  const Location = useLocation();
  const History = useHistory();
  const pathId = Location.pathname.split("/")[4];

  //Redux store
  const { allPopularGame, gameCount, currentPage, gameLoading } = useSelector(
    (state) => state.popular
  );
  //No of pages
  const totalPage = Math.ceil(gameCount / 36);

  //SCROLL TO TOP
  useEffect(() => {
    window.scrollTo(0, 0);
  }, [currentPage]);

  //Handlers
  const PrevHandler = () => {
    if (currentPage <= 1) {
      return;
    } else {
      dispatch(PrevPage());
      History.push(`/popular/games?page=${currentPage - 1}`);
    }
  };

  const NextHandler = () => {
    if (currentPage >= totalPage) {
      console.log("Hello");
      return;
    } else {
      dispatch(NextPage());
      History.push(`/popular/games?page=${currentPage + 1}`);
    }
  };
  //Fetch all popular games
  const dispatch = useDispatch();

  useEffect(() => {
    async function fetchGames(page) {
      const games = dispatch(AllPopularGame(page));
      return games;
    }
    fetchGames(currentPage);
  }, [dispatch, currentPage]);

  // {`${currentPage} /popular/games/${popularGames.id}`}
  return (
    <Popular>
      <h2>Popular Games </h2>
      <AnimateSharedLayout type="crossfade">
        <AnimatePresence>
          {pathId && <GameDetail pathId={pathId} curPage={currentPage} />} //child component
        </AnimatePresence>
        {gameLoading ? (
          <h2>Loading</h2>
        ) : (
          <Games>
            {allPopularGame.map((popularGames) => (
              <Link
                to={`/popular/games/${currentPage}/${popularGames.id}`}
                key={popularGames.id}
              >
                <Game
                  name={popularGames.name}
                  img={popularGames.background_image}
                  rating={popularGames.rating}
                  id={popularGames.id}
                  key={popularGames.id}
                  released={popularGames.released}
                />
              </Link>
            ))}
          </Games>
        )}
      </AnimateSharedLayout>
      <Page>
        <Button onClick={PrevHandler}>
          <span>Prev</span>
        </Button>
        <p>{currentPage}</p>
        <Button onClick={NextHandler}>
          <span>Next</span>
        </Button>
      </Page>
    </Popular>
  );
};
import React,{useffect}来自“React”;
//动画和样式
从“样式化组件”导入样式化;
从“帧运动”导入{motion,AnimatePresence,AnimateSharedLayout};
//REDUX与路由器
进口{
好的,
下一页,
前页,
}来自“./行动/群众行动”;
从“react-redux”导入{useSelector,useDispatch};
从“react router dom”导入{Link,useLocation,useHistory};
//组成部分
从“/games”导入游戏;
从“/GameDetail”导入游戏详细信息;
常量PopularGames=()=>{
//获取路径
const Location=useLocation();
const History=useHistory();
const pathId=Location.pathname.split(“/”[4];
//Redux商店
const{allPopularGame,gameCount,currentPage,gameLoading}=useSelector(
(state)=>state.popular
);
//页数
const totalPage=Math.ceil(gameCount/36);
//滚动到顶部
useffect(()=>{
滚动到(0,0);
},[currentPage]);
//处理者
常量PrevHandler=()=>{
如果(当前页){
如果(当前页面>=totalPage){
console.log(“你好”);
返回;
}否则{
调度(NextPage());
推送(`/popular/games?page=${currentPage+1}`);
}
};
//获取所有流行游戏
const dispatch=usedpatch();
useffect(()=>{
异步函数获取游戏(第页){
const games=dispatch(AllPopularGame(第页));
返回游戏;
}
获取游戏(当前页面);
},[dispatch,currentPage]);
//{`${currentPage}/popular/games/${popularGames.id}}
返回(
流行游戏

感谢您共享存储库!现在已经很清楚了。您正在使用链接并重新路由页面-因此,尽管组件是相同的,UI上没有重新绘制,但整个页面仍会再次挂载。这就是为什么每次单击卡片(甚至关闭卡片时!)都会触发useEffect的原因

您的UI状态由URL中的路径管理-这是一种非常糟糕的做法-尤其是考虑到您没有进行任何API调用来基于URL获取数据

以下是我的建议-

  • 用useState钩子替换当前从URL读取的pathID变量:

    const[activeGameID,setActiveGameID]=useState(null);

  • 用常规div替换用于包装游戏的链接组件,并将onClick处理程序传递给setActiveGameID:

    
    {popular.map((popularGames)=>(
    setActiveGameID(popularGames.id)}
    key={popularGames.id}
    >  
    ))}
    ```
    

  • 我认为您可能面临的问题是,您的动画取决于URL的更改-在这种情况下,我建议您使用其他方式来制作卡的动画。

    添加了“我的回复”的链接