history.push是否应该呈现与路线关联的组件?

时间:2020-02-14 10:28:17

标签: reactjs react-hooks react-router-v4 react-router-dom

因此,我正在创建一个向服务器请求数据的加载器组件,然后根据响应-然后加载器页面将它们重定向/重新路由到其他页面。

但是由于某些原因,history.push会更改路线,但不呈现该组件,而是保留在<LoaderPage>组件中。不知道我在想什么。所以请帮忙。

我用<LoaderPage>组件包装了所有页面,因为我的目标是每次用户访问任何路由时,<LoaderPage>组件首先呈现然后执行其工作,然后将用户重定向/重新路由到其他页面

loader.tsx

import React from 'react';
import { useHistory } from 'react-router-dom'
import { AnimatedLodingScreen } from './loaders/AnimatedLodingScreen'

type loaderProps = {
 children: React.ReactNode;
};

export const LoaderPage = ({ children }:loaderProps) => {
  const history = useHistory();
  React.useEffect(() => {
    const session = http.get('/some-route');
    session.then((result) => {
      if(result.authenticated) {
        history.push('home'); // when user is logged
      }
      history.push('/login'); // not authenticated
    }
  }, [])

  return (
    <AnimatedLodingScreen/>
  );
} 

app.tsx

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { observer } from 'mobx-react';
import { LoaderPage } from 'pages/loaders/LoaderPage';
import { SomeComponent1, SomeComponent2 } from 'pages/index'

export const App: React.FC = observer(() => {
  return (
    <BrowserRouter>
      <LoaderPage>
        <Route path='/home' exact component={SomeComponent1}/>
        <Route path='/login' exact component={SomeComponent2}/>
        // and so on... I have alot of routes in fact these routes are looped via .map and 
        // type-checked i just put it like this for simplicity
      </LoaderPage>
    </BrowserRouter>
  );
});

index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { App } from 'app/app';

ReactDOM.render(<App/>, document.getElementById('root'));

2 个答案:

答案 0 :(得分:1)

您的children组件所使用的LoaderPage道具并未用于其中的任何位置渲染,因此不会渲染任何东西。

export const LoaderPage = ({ children }:loaderProps) => {
  const history = useHistory();
  React.useEffect(() => {
    const session = http.get('/some-route');
    session.then((result) => {
      if(result.authenticated) {
        history.push('home'); // when user is logged
      }
      history.push('/login'); // not authenticated
    }
  }, [])

  return (
    {children || <AnimatedLodingScreen/>}
  );
} 

答案 1 :(得分:1)

您可以使用状态保存数据加载是否完成并根据该状态呈现子级

export const LoaderPage = ({ children }:loaderProps) => {
      const history = useHistory();
      const [isLoaded, setLoaded] = React.useState(false)
      const [redirectPath, setRedirectPath] = React.useState('')
      React.useEffect(() => {
        const session = http.get('/some-route');
        session.then((result) => {
          if(result.authenticated) {

            return setRedirectPath('/home') // when user is logged
          }
          setRedirectPath('/login')   // not authenticated

        }
      }, [])

  function redirectToPath() {
  setLoaded(true);
  history.push(redirectPath)
  }


  if(isLoaded) { return <>{children}</> }
  return <AnimatedLodingScreen onAnimationEnd={redirectToPath} /> // onAnimationEnd is the function passed as prop to the component that should be invoked on animation ends

}