React Router history.push 无限循环

Posted

技术标签:

【中文标题】React Router history.push 无限循环【英文标题】:React Router history.push in infinite loop 【发布时间】:2021-10-05 17:47:48 【问题描述】:

我有一个页面(“/paymentssucess”)。在这个页面中,我使用了 react-countdown-circle-timer 组件 (https://github.com/vydimitrov/react-countdown-circle-timer#props-for-both-reactreact-native)。到达此页面(“/paymentsuccess”)后,倒计时。倒计时归零后,我想将用户重定向回主页(“/”)。

为了实现这一点,对于 CountdownCircleTimer 组件,当 onComplete 时,我将状态 initialMount 设置为 false。

            <CountdownCircleTimer
              onComplete=() => 
                setInitialMount(false);
                return [true, 1500];
              
              isPlaying
              duration=2
              colors=[
                ["#004777", 0.33],
                ["#F7B801", 0.33],
                ["#A30000", 0.33],
              ]
            >
              renderTime
            </CountdownCircleTimer>

鉴于 initialMount 已更改,我的 useEffect(在支付成功组件中)将启动并将用户重定向到“/”。我在这里使用 history.push("/")。

  useEffect(() => 
    if (initialMount !== true) 
      console.log("On change in status,");
      console.log(initialMount);
      history.push("/");
    
  , [initialMount, history]);

我能够成功地将用户重定向回“/”。但是在到达“/”时,他们又被重定向回/paymentsuccess。然后从 /paymentsuccess 返回到 / 然后循环继续。无限循环。

知道我在这里做错了什么吗? :( 我需要停止这个循环,让用户回到 / 并停在那里。

我正在使用 react-router-dom 中的路由器和历史中的 createBrowserHistory。

下面是我的支付成功组件的完整代码

import React,  useEffect, useStatem from "react";
import  useHistory  from "react-router-dom";
import  makeStyles  from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import  CountdownCircleTimer  from "react-countdown-circle-timer";

function PaymentSuccess() 
  const useStyles = makeStyles((theme) => (
    root: 
      flexGrow: 1,
    ,
  ));

  const classes = useStyles();
  const history = useHistory();
  const [initialMount, setInitialMount] = useState(true);

  useEffect(() => 
    console.log("On component mount, status is");
    console.log(initialMount);
  , []);

  useEffect(() => 
    return () => 
      console.log("On component unmount, status is");
      setInitialMount(true);
      console.log(initialMount);
    ;
  , []);

  useEffect(() => 
    if (initialMount !== true) 
      console.log("On change in status,");
      console.log(initialMount);
      history.push("/");
    
  , [initialMount, history]);

  const renderTime = ( remainingTime ) => 
    if (remainingTime === 0) 
      return <div className="timer">Starting...</div>;
    
    return (
      <div className="timer">
        <div className="value">remainingTime</div>
      </div>
    );
  ;

  return (
    <div className=classes.root>
      <Grid container spacing=0>
        <Grid item xs=6 sm=6>
          <Paper
            className="paymentSuccessLeftPaper"
            variant="outlined"
            square
          ></Paper>
        </Grid>
        <Grid item xs=6 sm=6>
          <Paper className="paymentSuccessRightPaper" variant="outlined" square>
            <h1>Payment Success</h1>
            <CountdownCircleTimer
              onComplete=() => 
                setInitialMount(false);
                return [true, 1500];
              
              isPlaying
              duration=2
              colors=[
                ["#004777", 0.33],
                ["#F7B801", 0.33],
                ["#A30000", 0.33],
              ]
            >
              renderTime
            </CountdownCircleTimer>
          </Paper>
        </Grid>
      </Grid>
    </div>
  );


export default PaymentSuccess;

我检查了我的“/”页面,我认为那里没有任何逻辑重定向到“/paymentsuccess”。页面(“/”)代码如下。

import React from "react";

import  makeStyles  from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import Button from "@material-ui/core/Button";
import Link from "@material-ui/core/Link";

function LandingPage() 
  const useStyles = makeStyles((theme) => (
    root: 
      flexGrow: 1,
    ,
    paper: 
      minHeight: "100%",
      padding: theme.spacing(0),
      textAlign: "center",
      color: theme.palette.text.secondary,
    ,
  ));

  const classes = useStyles();

  return (
    <div className=classes.root>
      <Grid container spacing=0>
        <Grid item xs=4 sm=4>
          <Paper className=classes.paper variant="outlined" square>
            <h1>Photo Strips</h1>
            <Button variant="contained" color="primary">
              <Link href="/photo10">SELECT</Link>
            </Button>
          </Paper>
        </Grid>
        <Grid item xs=4 sm=4>
          <Paper className=classes.paper variant="outlined" square>
            <h1>Photo Strips and GIF</h1>
            <Button variant="contained" color="primary">
              <Link href="/photogif12">
                SELECT
              </Link>
            </Button>
          </Paper>
        </Grid>
        <Grid item xs=4 sm=4>
          <Paper className=classes.paper variant="outlined" square>
            <h1>Photo Strips and Boomerang</h1>
            <Button variant="contained" color="primary">
              <Link href="/photoboomerang12">
                SELECT
              </Link>
            </Button>
          </Paper>
        </Grid>
      </Grid>
    </div>
  );


export default LandingPage;

提前谢谢大家!感谢所有帮助和建议

更新

下面是路由器代码

import React from "react";
import  Router, Switch  from "react-router-dom";

import LandingPage from "./components/LandingPage";
import Photo10 from "./components/Photo10";
import PhotoGIF12 from "./components/PhotoGIF12";
import PhotoBoomerang12 from "./components/PhotoBoomerang12";
import PaymentSuccess from "./components/PaymentSuccess";

import DynamicLayout from "./router/DynamicLayout";

import  history  from "./helpers/history";

const App = () => 
  return (
    <Router history=history>
      <div className="App">
        <Switch>
          <DynamicLayout
            exact
            path="/"
            component=LandingPage
            layout="LANDING_NAV"
          />
          <DynamicLayout
            exact
            path="/photo10"
            component=Photo10
            layout="PHOTO10_PAGE"
          />
          <DynamicLayout
            exact
            path="/photogif12"
            component=PhotoGIF12
            layout="PHOTOGIF12_PAGE"
          />
          <DynamicLayout
            exact
            path="/photoboomerang12"
            component=PhotoBoomerang12
            layout="PHOTOBOOMERANG12_PAGE"
          />
          <DynamicLayout
            exact
            path="/paymentsuccess"
            component=PaymentSuccess
            layout="PAYMENTSUCCESS_PAGE"
          />
        </Switch>
      </div>
    </Router>
  );
;

export default App;

下面是DynamicLayout组件的代码

import React from "react";

const DynamicLayout = (props) => 
  const  component: RoutedComponent, layout  = props;

  const actualRouteComponent = <RoutedComponent ...props />;

  switch (layout) 
    case "LANDING_NAV": 
      return <>actualRouteComponent</>;
    

    case "PHOTO10_PAGE": 
      return <>actualRouteComponent</>;
    

    case "PHOTOGIF12_PAGE": 
      return <>actualRouteComponent</>;
    

    case "PHOTOBOOMERANG12_PAGE": 
      return <>actualRouteComponent</>;
    

    case "PAYMENTSUCCESS_PAGE": 
      return <>actualRouteComponent</>;
    

    default: 
      return (
        <>
          <h2>Default Nav</h2>
          actualRouteComponent
        </>
      );
    
  
;

export default DynamicLayout;

【问题讨论】:

我认为您的问题出在“/”页面代码中,您是否检查过是否有重定向到 /paymentsuccess?好像你忘记了那里的 [ ] 括号...... 我在上面的代码中找不到任何问题。我怀疑问题出在路由器级别。你能显示你的应用程序的路由代码吗? @ArthurChaloin 完成。以上更新。非常感谢 @Fresh Done。我也在上面包含了我的“/”代码。非常感谢 【参考方案1】:

当您更改 useEffect 中变量的值并且该变量也添加到 useEffect 依赖数组中时,会出现此问题,因此,当您的 useEffect 由于依赖数组中存在该变量而更改值时,它再次调用 useEffect 因此无限循环发生

所以只需从依赖数组中删除“历史”变量

【讨论】:

嗨。感谢您的建议。我已经删除了我的依赖数组中的历史记录。但是错误仍然存​​在。我被重定向回“/”,然后从“/”我回到“/paymentsuccess”,在一个无限循环中不停地循环。不知何故,“/”处发生了一些事情,然后直接返回“/paymentsuccess”……我正在使用 Redux 来管理我的状态。这可能是一个原因吗?

以上是关于React Router history.push 无限循环的主要内容,如果未能解决你的问题,请参考以下文章

Ionic/React/TypeScript,使用 react-router history.push、history.replace 和 history.goBack 动画触发两次

React-router v4 this.props.history.push(...) 不工作

React Router history.push 无限循环

React Router 4 和 props.history.push

Redux & React Router:结合调度和导航(history.push)

在 react-router-v4 中使用 history.push in action creator?