2017-06-05 3 views
0

私はアプリケーションでルーティングするために反応ルータv4を使用しています。コンポーネント、サガおよびレデューサーは非同期にロードされます。このような場合に私は今どのようにプライベートルーティングとパブリックルーティングを実装できますか?ここで反応ルータv4で非同期ルートへのプライベートルートを作成

はあなたのReduxの店であなたの歴史を同期するreact-router-reduxを使用していると仮定すると、ルーティングおよびロード

/** 
* A wrapper component that will lazily render a component after it has been loaded. 
*/ 
class Bundle extends Component { 
    static contextTypes = { 
    store: React.PropTypes.object 
    }; 

    state = { 
    // short for "module" but that's a keyword in js, so "mod" 
    mod: null 
    }; 

    componentWillMount() { 
    this.load(this.props); 
    } 

    /* istanbul ignore next */ 
    componentWillReceiveProps(nextProps) { 
    if (nextProps.load !== this.props.load) { 
     this.load(nextProps); 
    } 
    } 

    load(props) { 
    this.setState({ 
     mod: null 
    }); 
    props.load(this.context.store, mod => { 
     this.setState({ 
     // handle both es imports and cjs 
     mod: mod.default ? mod.default : mod 
     }); 
    }); 
    } 

    render() { 
    // eslint-disable-next-line no-unused-vars 
    const { load, ...otherProps } = this.props; 
    return this.state.mod && <this.state.mod {...otherProps} />; 
    } 
} 

const AsyncRoute = ({ load, ...others }) => (
    <Route {...others} render={props => <Bundle load={load} {...props} />} /> 
); 

AsyncRoute.propTypes = { 
    computedMatch: React.PropTypes.object, 
    path: React.PropTypes.string, 
    load: React.PropTypes.func 
}; 

export default AsyncRoute; 


// how can i make private route with different layout not a children of App 
function Routes({ location }) { 
    return (
    <Switch location={location}> 
     <AsyncRoute exact path="/" load={loadHomePage} /> 
     <AsyncRoute exact path="/signup" load={loadSignupPage} /> 
     <AsyncRoute path="" load={loadNotFoundPage} /> 
    </Switch> 
); 
} 


export default (store, cb) => { 
    const { injectReducer, injectSagas } = getAsyncInjectors(store); 
    const importModules = Promise.all([ 
    import("./reducer"), 
    import("./sagas"), 
    import("./index") 
    ]); 

    importModules.then(([reducer, sagas, component]) => { 
    injectReducer("signup", reducer.default); 
    injectSagas(sagas.default); 

    cb(component); 
    }); 

    importModules.catch(errorLoading); 
}; 

const render = messages => { 
    ReactDOM.render(
    <Provider store={store}> 
     <ConnectedRouter history={history}> 
      <App /> 
     </ConnectedRouter> 
    </Provider>, 
    document.getElementById("app") 
); 
}; 

答えて

0

するためのコードで、あなたはから最新のLOCATION_CHANGEアクションタイプを取るメインチャンクにサガを作成することができますreact-router-reduxを開き、APIを呼び出して認証をリフレッシュしてください(authレデューサーに保存してください)。

プライベートとパブリックの構成要素を区別するために、あなたはauth状態が有効になるまで、それは非同期にプライベートチャンクを読み込むから延期することをBundleなどを変更することができます。ここで

サガ/ auth.js

import { LOCATION_CHANGE } from 'react-router-redux' 

function *checkAuth() { 
    yield put(authenticateStart()) 
    // Assuming using some token authentication 
    const token = yield select(state => state.auth.token) 
    const result = yield call(Api.refreshAuth, token) 
    if (result.isAuthenticated) { 
     yield put(authenticateSuccess(result.user) 
    } else { 
     // Need auth 
     yield put(authenticateError()) 
    } 
} 
// Put this saga on main bundle 
function *authSaga() { 
    yield* takeLatest(LOCATION_CHANGE, checkAuth) 
} 

bundle.js

class Bundle extends Component { 
    static contextTypes = { 
    store: React.PropTypes.object 
    }; 

    state = { 
    // short for "module" but that's a keyword in js, so "mod" 
    mod: null 
    }; 

    componentWillMount() { 
    if (this.props.isProtected && !this.props.isAuthenticated) 
     return 
    this.load(this.props); 
    } 

    /* istanbul ignore next */ 
    componentWillReceiveProps(nextProps) { 
    // Modify similar to above 
    } 

    load(props) { 
    this.setState({ 
     mod: null 
    }); 
    props.load(this.context.store, mod => { 
     this.setState({ 
     // handle both es imports and cjs 
     mod: mod.default ? mod.default : mod 
     }); 
    }); 
    } 

    render() { 
    // eslint-disable-next-line no-unused-vars 
    const { load, ...otherProps } = this.props; 
    return this.state.mod && <this.state.mod {...otherProps} />; 
    } 
} 

export default connect(state => ({ isAuthenticated: state.auth.isAuthenticated }))(Bundle) 
+0

いくつかのコードをスケッチしているあなたは垣間見るを表示することができますか?私は完全に理解していませんでした。 – Serenity

+0

コードスケッチを追加 –

関連する問題