简体   繁体   中英

React-router : conditionally redirect at render time

So I have this basic component <Redirectable /> :

import React from 'react';
import {
  useParams,
  useHistory,
  Redirect,
} from 'react-router-dom';

export default () => {
  const history = useHistory();
  const {id} = useParams();

  if (!checkMyId(id) {
    // invalid ID, go back home
    history.push('/');
  }
  return <p>Hey {id}</p>
}

But I get the following error:

Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.

I also tried: <Redirect push to="/" /> , but same error.

What's the correct way to handle this? I read about onEnter callback at <Router /> level, but as far as I'm concerned, the check should happen at <Redirectable /> level.

There should be a solution, shouldn't it? I don't feel like I'm doing something completely anti-react-pattern, am I?

This seems to do the trick. I was not able to find any documentation as to why this occures. All I was able to find was different examples with callbacks but this solved it for me.

import React from 'react';
import {
  useParams,
  useHistory,
  Redirect,
} from 'react-router-dom';

const MyComponent = () => {
  const history = useHistory();
  const {id} = useParams();

  if (!checkMyId(id) {
    // invalid ID, go back home
    history.push('/');
  }
  return <p>Hey {id}</p>
}
export default MyComponent;

It seems that react may recognize export default () => { as a pure component and so side effects are prohibited.

Yes, it seems to me you are written the component in a anti pattern way. Can you please update like below:

const Rediractabke = () => {
        const history = useHistory();
        const {id} = useParams();

        if (!checkMyId(id) {
             // invalid ID, go back home
             history.push('/');
         }
         return <p>Hey {id}</p>
  }

  export default as Redirectable;

@c0m1t was right, the solution was to use useEffect :

import React, {useEffect} from 'react';
import {
  useParams,
  useHistory,
  Redirect,
} from 'react-router-dom';

export default () => {
  const history = useHistory();
  const {id} = useParams();

  useEffect(() => {
    if (!checkMyId(id) {
      // invalid ID, go back home
      history.push('/');
    }
  })

  return <p>Hey {id}</p>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM