React Router onEnter 未按预期工作 [英] React Router onEnter not working as intended

查看:37
本文介绍了React Router onEnter 未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个用于教育目的的基本 react-login 应用程序并验证我正在使用 React-router 的 onEnter 属性功能的路由

从'axios'导入axios;var Authentication = (nextState, replace, callback) =>{axios.get('/api/getuser').then((res) => {if(res.data != '') {替换('帐户/墙')}打回来()}).catch((错误) => {打回来()})}导出默认值 (<路由组件={Root} ><Route path='/' component={Home} onEnter={Authentication}/><Route path='/login' component={Login} onEnter={Authentication}/><Route path='/signup' component={Registration} onEnter={Authentication}/><Route path='/account/wall' component={Wall}/><Route path='*' component={Notfound}/></路线>);

一切都按预期工作但是我无法理解为什么路由器会在我尝试 // 时将 Home 组件渲染一秒钟然后将路由替换为 /account/wall代码>登录后路由??如果我在登录后尝试 /login/signup ,也会发生同样的事情,有没有办法解决这个问题?

我已经尝试通过在检查用户时呈现空 <div> 在 componentWillMount 方法(我猜这不是反应方式)中对用户进行身份验证来解决此问题,但这也会呈现空页面眨眼一秒钟,而不是正确的方法.

所以我只想渲染 /account/wall 如果用户在没有任何中间件渲染的情况下通过身份验证.我能做什么??

解决方案

我无法写出确切的示例,因为每个人的实现都不同,但我将正确地编写一个 HelloWrapper 组件示例,它包装了任何组件,如果它收到 sayHelloprop 为 true,它呈现 Hello 而不是实际组件,您可以检查登录道具并重定向或显示登录组件..在您的情况下.

  1. 编写一个函数将 props 从实际组件复制到包装器

HoistNonReactStatistics.tsx 或 jsx(我使用打字稿)

 const REACT_STATICS = {childContextTypes:真,上下文类型:真,默认道具:真,显示名称:真,getDefaultProps: 真,混合:真实,道具类型:真实,类型:真实};const KNOWN_STATICS = {名称:真实,长度:真实,原型:真实,来电者:真的,论据:真实,数量:真实};导出默认函数 hoistStatics(targetComponent, sourceComponent) {var keys = Object.getOwnPropertyNames(sourceComponent);for (var i = 0; i 

  1. 编写包装函数,返回包装好的组件

     import * as React from 'react';从./HoistNonReactStatistics"导入 HoistNonReactStatistics导出函数 HelloWrapper(){返回函数 HellowWrapComponent(DecoratedComponent) {class WrappendComponent extends React.Component<{sayHello?:boolean},{}>{构造函数(道具){超级(道具);}componentWillMount(){/** 在这里做一些登录检查并在需要时重定向 **/}componentWillReceiveProps(nextProps){/** 在这里做一些登录检查并在需要时重定向 **/}使成为(){如果(this.props.sayHello){return 

    你好

    }别的{返回 <装饰组件/>}}}/** 如果你使用 redux 然后在返回组件上应用 connect 方法,这样它就可以访问所需的 auth reducer 数据**/返回 HoistNonReactStatistics(WrappendComponent,DecoratedComponent);}}

    1. 创建一个const(不确定jsx是否需要这一步,但是typescript不允许直接包装组件,因为我没有声明包装函数来接受参数

    export const requireHellow = HelloWrapper();

    1. 现在使用函数来扭曲任何组件,我在导出时使用它,但您也可以在 Route 的组件 prop 中进行

    导出默认 requireHellow(SomeComponent);

现在每当你使用这个 SomeComponent 并且它有 sayHello 属性为 true 它会渲染 Hello 否则渲染实际组件

I am building a basic react-login app for educational purposes and to authenticate a route I am using React-router's onEnter prop functionality

import axios from 'axios';    

var Authentication = (nextState, replace, callback) => {
    axios.get('/api/getuser')
    .then((res) => {
        if(res.data != '') {
          replace('account/wall')
        }
        callback()
    })
    .catch((err) => {
        callback()
    })

}

export default (
  <Route component={Root}  >
      <Route path='/' component={Home} onEnter={Authentication}/>
      <Route path='/login' component={Login} onEnter={Authentication}/> 
      <Route path='/signup' component={Registration} onEnter={Authentication}/> 
      <Route path='/account/wall' component={Wall}/>
      <Route path='*' component={Notfound} />
  </Route>

);

Everything is working as intended But it is beyond me why the router render the Home component for a blink second and THEN replace the route to /account/wall when I try / route after logging in?? Same thing happen if I try /login or /signup after logging in., Is there anyway to fix this behavior ??

I already tried to solve this by authenticating the user in componentWillMount method (which is not the react way i guess) by rendering empty <div> when checking for user but that also renders empty page for a blink second and not the correct way to do it.

So I just want to render /account/wall if user is authenticated without any middleware renders. What can I do??

解决方案

I can't write the exact example because everyone's implementation differs, but I am going to right a HelloWrapper component example which wraps any component and if it receive the sayHello prop to true, it render the Hello instead of actual component, you can check the login props and redirect or show login component..in your case.

  1. Write a function to copy props form actual component to wrapper

HoistNonReactStatistics.tsx or jsx ( I use typescript)

    const REACT_STATICS = {
    childContextTypes: true,
    contextTypes: true,
    defaultProps: true,
    displayName: true,
    getDefaultProps: true,
    mixins: true,
    propTypes: true,
    type: true
    };

    const KNOWN_STATICS = {
    name: true,
    length: true,
    prototype: true,
    caller: true,
    arguments: true,
    arity: true
    };

    export default function hoistStatics(targetComponent, sourceComponent) {
    var keys = Object.getOwnPropertyNames(sourceComponent);
    for (var i = 0; i < keys.length; ++i) {
      const key = keys[i];
      if (!REACT_STATICS[key] && !KNOWN_STATICS[key]) {
        try {
          targetComponent[key] = sourceComponent[key];
        } catch (error) {}
      }
    }
    return targetComponent;
    }

  1. write wrapper function which will return wrapped component

     import * as React from 'react';
     import HoistNonReactStatistics from "./HoistNonReactStatistics"
     export function HelloWrapper(){
    
     return function HellowWrapComponent(DecoratedComponent) {
    
     class WrappendComponent extends React.Component<{sayHello?:boolean},{}>{
        constructor(props){
          super(props);
        }
        componentWillMount(){
         /** do some login check here and redirect if required **/
         }
        componentWillReceiveProps(nextProps){
         /** do some login check here and redirect if required **/
         }
       render(){
         if(this.props.sayHello){
           return <div>Hello</div>
         }else{
           return <DecoratedComponent />
         }
       }
     }
     /** if you use redux then also apply the connect method on return component so it get access to required auth reducer data**/
     return HoistNonReactStatistics(WrappendComponent,DecoratedComponent);
     }
    }
    

    1. create a const ( not sure if this step is required for jsx, however typescript doesn't allow to wrap a component directly because I didn't declare wrapper function to accept arguments

    export const requireHellow = HelloWrapper();

    1. now warp any component with function, I used it at the time of export but you can also do it in Route's component prop

    export default requireHellow(SomeComponent);

now whenever you use this SomeComponent and it has sayHello prop to true it will render Hello otherwise render the actual component

这篇关于React Router onEnter 未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆