【问题标题】:migrate to react-router v4迁移到 react-router v4
【发布时间】:2017-04-19 08:24:08
【问题描述】:

我尝试迁移到 react-router v4,我应该从哪里开始?对于大多数路径,我需要身份验证和重定向。我安装了最后一个 react-router-dom@next 和 react-router@next。现在当用户没有登录时重定向到登录页面, 我也有登录回调,但有一个错误 WebSocket 连接到 'ws://localhost:9998/sockjs-node/472/gnanejj3/websocket' 失败:WebSocket 在连接建立之前关闭。

application.js

      import React, {Component} from 'react'
import {connect} from 'react-redux'
import {IntlProvider} from 'react-intl'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme'

import theme from './theme'

import * as AuthActions from './actions/auth'
import Routes from './routes'

export class Application extends Component {
    static propTypes = {
        locale: React.PropTypes.string.isRequired,
        messages: React.PropTypes.objectOf(React.PropTypes.string.isRequired).isRequired,
        login: React.PropTypes.func.isRequired,
        redirectToLoginPage: React.PropTypes.func.isRequired,
        isLoggedIn: React.PropTypes.bool.isRequired,
    };

    render = () =>
        <IntlProvider locale={this.props.locale} messages={this.props.messages}>
            <MuiThemeProvider muiTheme={getMuiTheme(theme)}>
                <Routes />
            </MuiThemeProvider>
        </IntlProvider>;
}

export default Application

routes.js:

import React from 'react'
import {connect} from 'react-redux'
import {BrowserRouter, Route, Link ,Redirect, withRouter, Switch} from 'react-router-dom'

import Root from './components/root'
import Home from './components/homePage'
import Devices from './components/devices'
import Users from './components/users'
import AddOrEditUser from './components/users/addOrEdit'
import Plans from './components/plans'
import ServerSettings from './components/settings'
import About from './components/aboutPage'
import Patients from './components/patients'
import AddOrEditPatient from './components/patients/addOrEdit'
import Commissioning from './components/commissioning'
import * as AuthActions from './actions/auth'
import redirectToLoginPage from './api/auth'

const Routes = ({isLoggedIn, redirectToLoginPage, login}) =>
    <BrowserRouter>
        <Switch>
            <Route path='/' render={({location}) => {
                if (!isLoggedIn)
                    redirectToLoginPage()
                return (
                    <Root>
                        <Switch>
                            <Route path='/home' component={Home} />
                            <Route path='/devices' component={Devices} />
                            <Route path='/users' component={Users} />
                            <Route path='/users/add' component={AddOrEditUser}/>
                            <Route path='/users/edit/:personId' component={AddOrEditUser}/>

                            <Patients path='/patients' render={() =>
                                    <Switch>
                                        <Route path='/add' component={AddOrEditPatient} />
                                        <Route path='/edit/:personId' component={AddOrEditPatient} />
                                    </Switch>
                                }
                            />

                            <Route path='/plans' component={Plans} />
                            <Route path='/commissioning' component={Commissioning} />
                            <Route path='/server-settings' component={ServerSettings} />
                            <Route path='/about' component={About} />
                        </Switch>
                    </Root>)
            }}
            />
            <Route path='/login-callback' render={() => {
                if (isLoggedIn)
                    login()
                return <Root />
            }}
            />
        </Switch>
    </BrowserRouter>

Routes.propTypes = {
    // authenticate: React.PropTypes.func.isRequired,
    // processLoginCallback: React.PropTypes.func.isRequired,
    login: React.PropTypes.func.isRequired,
    redirectToLoginPage: React.PropTypes.func.isRequired,
    isLoggedIn: React.PropTypes.bool.isRequired,
}

export const mapDispatchToProps = dispatch => ({
    login: () => dispatch(AuthActions.login()),
    redirectToLoginPage: () => dispatch(AuthActions.redirectToLoginPage()),
})

export const mapStateToProps = state => ({
    isLoggedIn: state.auth.isLoggedIn,
    locale: state.intl.locale,
    messages: state.intl.messages,
})

export default connect(mapStateToProps, mapDispatchToProps)(Routes)

【问题讨论】:

  • v4 的嵌套路由是对人类的犯罪。让自己摆脱无情的精神痛苦并查看Router5 with React - 或者找到一个类似的轻量级和明智的替代方案,将嵌套路由视为非常重要 - 不是解决方法......

标签: reactjs react-router react-redux react-router-v4


【解决方案1】:

这是一个复杂的问题,StackOverflow 响应框对它的限制太大。我写了一个冗长的迁移指南。如果您对 react-router v2:v3 感到满意,这将是您迁移的好资源:

https://medium.com/@francoisz/react-router-v4-unofficial-migration-guide-5a370b8905a

【讨论】:

    【解决方案2】:

    由于v4不支持嵌套路由,所以这段代码

    <Route path='/' render={({location}) => {
            if (!this.props.isLoggedIn)
                this.props.redirectToLoginPage()
            return ( ...
    

    可能会停止工作

    我通过为组件创建一些包装器来解决问题。例如

    const enforceLoginValidation = (children) => {
      const fn = ({ match }) => { 
        if (!this.props.isLoggedIn) {
           this.props.redirectToLoginPage()
           return
        }
        // to pass react-router's match to the children 
        const extendedChild = React.cloneElement(children, { match });
        return extendedChild;
      };
      return fn;
    };
    
    ...
    
    const HomePage = enforceLoginValidation(
      <Home />
    );
    
    ....
    <Route path='/home' component={HomePage} />
    

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 2017-10-04
      • 2020-07-05
      • 2022-01-17
      • 1970-01-01
      • 2022-10-11
      相关资源
      最近更新 更多