2017-09-26 24 views
1

我似乎没有掌握composeRedux的概念,因为我无法按预期工作。如何正确使用组合将HOC封装在React-Redux中的受保护路由

我目前在我的一条受保护路线上有两个嵌套HOC:一个确保用户在导航到受保护路线之前进行了验证,另一个只是一个计时器,如果它们处于空闲状态,则将它们从受保护路线中踢出。

我想利用compose,这样我可以在肝卵圆细胞清理我的代码,而不是我的窝保护途径。

这是我目前有:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { createStore, applyMiddleware, compose } from 'redux'; 
import thunk from 'redux-thunk'; 
import { BrowserRouter, Switch, Route } from 'react-router-dom'; 
import { routerMiddleware, ConnectedRouter } from 'react-router-redux'; 

import createHistory from 'history/createBrowserHistory'; 

// Render on every route 
import App from './components/app'; 

// Route specific 
import Signin from './containers/authentication/signin'; 
import Signout from './containers/authentication/signout'; 
import Home from './components/home'; 

// HoC to wrap protected routes in 
import RequireAuth from './helpers/require_auth'; 
import Timer from './helpers/timer'; 

// Reducers 
import rootReducer from './reducers'; 

// SCSS for the project 
import styles from '../assets/scss/main.scss'; 

const history = createHistory(); 

const initialState = {}; 
const enhancers = []; 
const middleware = [thunk, routerMiddleware(history)]; 

if (process.env.NODE_ENV === 'development') { 
    const devToolsExtension = window.devToolsExtension 

    if (typeof devToolsExtension === 'function') { 
     enhancers.push(devToolsExtension()) 
    } 
} 

const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers); 
const store = createStore(rootReducer, initialState, composedEnhancers); 

ReactDOM.render(
    <Provider store={store}> 
     <ConnectedRouter history={history}> 
      <div> 
       <App /> 
       <Switch> 
        <Route exact path='/home' component={LeftSite(RequireAuth(Home))} /> 
        <Route exact path='/auth/signout' component={Signout} /> 
        <Route exact path='/auth/signin' component={Signin} /> 
        <Route exact path='/' component={Signin} /> 
       </Switch> 
      </div> 
     </ConnectedRouter> 
    </Provider> 
    , document.querySelector('.container')); 

我已经试过被修改,像这样:

const composedEnhancers = compose(
          applyMiddleware(...middleware), 
          ...enhancers 
         ); 

const protectedRoutes = compose(
          applyMiddleware(RequireAuth, LeftSite)        
         ); 

const store = createStore(rootReducer, initialState, composedEnhancers, protectedRoutes); 

ReactDOM.render(
    <Provider store={store}> 
     <ConnectedRouter history={history}> 
      <div> 
       <App /> 
       <Switch> 
        <Route exact path='/home' component={protectedRoutes(Home)} /> 
        <Route exact path='/auth/signout' component={Signout} /> 
        <Route exact path='/auth/signin' component={Signin} /> 
        <Route exact path='/' component={Signin} /> 
       </Switch> 
      </div> 
     </ConnectedRouter> 
    </Provider> 
    , document.querySelector('.container')); 

这只是导致Cannot call a class as a function。这里是肝卵圆细胞之一,因为它们都具有相似的结构:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { authRequired } from '../actions/authentication'; 

export default function(ComposedComponent) { 
    class AuthenticationRequired extends Component { 

     // Check if the user has a token when protected route component is about to mount 
     // Route them to/if they do not 
     componentWillMount() { 
      if (!sessionStorage.getItem('token')) { 
       this.props.authRequired(); 
      } 
     } 

     // If the component will be updated then also check if user is authorized 
     componentWillUpdate() { 
      if (!sessionStorage.getItem('token')) { 
       this.props.authRequired(); 
      } 
     } 

     // Render the component if passing these checks 
     render() { 
      return <ComposedComponent {...this.props} /> 
     } 
    } 

    // Conenct to the authRequired action 
    return connect(null, { authRequired })(AuthenticationRequired); 
} 

我曾尝试与不同的错误几个变化。我不会把它们全部发布。我在这里有什么似乎可能接近正确的答案......也许?

我没有通过文档阅读,我没有发现我的情况有所帮助:

https://paulkogel.gitbooks.io/redux-docs/content/docs/api/compose.html

所以我的问题是:

我应该如何结构compose

该怎么做我把它只是我的保护路线?

回答

1

像文档说,compose实际上做的东西很简单,从概念上:

All compose does is let you write deeply nested function transformations without the rightward drift of the code. Don’t give it too much credit!

因此,让我们假设你有三个非常简单的功能是这样的:

const capitalize = str => str.toUpperCase(); 
const takeFirstChar = str => str[0]; 
const prependHello = str => 'hello' + str; 

如果你想用一排三个,不使用compose,它会成为网元泰德称这样的:

const originalValue = 'test'; 
console.log( capitalize(takeFirstChar(prependHello(originalValue)))) 
// prints 'H' 
// (the first letter from the appended 'hello', capitalized) 

如何看第一个函数被调用(prependHello)也是一路向右?这就是“代码向右移动”的意思。

但随着compose我们,相反,它这样写:

// NOTE the order of the arguments! 
// The bottom one is applied first, then middle one, then the top one 
const prependHelloAndTakeFirstCharToUpper = compose(
    capitalize, 
    takeFirstChar, 
    prependHello 
); 

console.log(prependHelloAndTakeFirstCharToUpper(originalValue) ) 
// still prints 'H' 

目前尚不清楚如何你在哪里使用您的HOC的时候他们的工作之前,但如果你没有以前那么涉及到的东西像applyMiddleWare那可能现在也不应该在那里。

我的猜测,不知道更多关于你的代码,是它应该努力做这样的事情:

const protectedRoutes = compose(RequireAuth, LeftSite); 

// further down 
<Route exact path='/home' component={protectedRoutes(Home)} /> 

而且我认为你可以从你的论点删除您protectedRoutescreateStore

+0

是的,我给它太多的信用和复杂化。我把它从'createStore'中拿出来了,它现在按照预期工作。谢谢! – sockpuppet

+0

没问题!很高兴听到它现在的作品! – jonahe