2016-07-25 6 views
29

私はサーバーからのトークン認証を持っているので、私のReduxアプリケーションが最初に読み込まれると、このサーバーにユーザーが認証されているかどうかを確認する必要があります私はトークンを取得する必要があります。React/Redux - アプリケーションの読み込み/起動時にアクションを実行する

私はReduxコアのINITアクションを使用することはお勧めできませんので、アプリケーションがレンダリングされる前にアクションをディスパッチするにはどうすればよいですか?

答えて

8

私が反応し、ルータをonEnter小道具を使用してこの問題を解決しました。これは、コードがどのように見えるかです:

// this function is called only once, before application initially starts to render react-route and any of its related DOM elements 
// it can be used to add init config settings to the application 
function onAppInit(dispatch) { 
    return (nextState, replace, callback) => { 
    dispatch(performTokenRequest()) 
     .then(() => { 
     // callback is like a "next" function, app initialization is stopped until it is called. 
     callback(); 
     }); 
    }; 
} 

const App =() => (
    <Provider store={store}> 
    <IntlProvider locale={language} messages={messages}> 
     <div> 
     <Router history={history}> 
      <Route path="/" component={MainLayout} onEnter={onAppInit(store.dispatch)}> 
      <IndexRoute component={HomePage} /> 
      <Route path="about" component={AboutPage} /> 
      </Route> 
     </Router> 
     </div> 
    </IntlProvider> 
    </Provider> 
); 
+5

明確な反応ルータ4はonEnterをサポートしていません。 –

+0

IntlProviderは、より良い解決策を提案します。下記の私の答えを参照してください。 –

34

ルートcomponentDidMountメソッドでアクションをディスパッチできます。renderメソッドでは、認証ステータスを確認できます。このような

何か:

class App extends Component { 
    componentDidMount() { 
    this.props.getAuth() 
    } 

    render() { 
    return this.props.isReady 
     ? <div> ready </div> 
     : <div>not ready</div> 
    } 
} 

const mapStateToProps = (state) => ({ 
    isReady: state.isReady, 
}) 

const mapDispatchToProps = { 
    getAuth, 
} 

export default connect(mapStateToProps, mapDispatchToProps)(App) 
+0

この回答は正しいものです。 –

+1

私にとっては、 'componentWillMount()'がそれをしました。私はApp.jsの 'mapDispatchToProps()'にすべてのディスパッチ関連のアクションを呼び出す単純な関数を定義し、 'componentWillMount()'でそれを呼び出しました。 – Froxx

+0

これは素晴らしいですが、mapDispatchToPropsを使用する方がより説明的です。代わりにmapStateToPropsを使用する理由は何ですか? – adc17

10

私はこのために提案されているすべてのソリューションで満足していませんでしたし、私がレンダリングされる必要があるクラスを考えていたことを私に起こりました。スタートアップ用のクラスを作成してからcomponentDidMountメソッドにプッシュして、renderに読み込み画面を表示させるだけの場合はどうなりますか?その後、

<Provider store={store}> 
    <Startup> 
    <Router> 
     <Switch> 
     <Route exact path='/' component={Homepage} /> 
     </Switch> 
    </Router> 
    </Startup> 
</Provider> 

そして、このようなものがあります:非同期アプリケーションを初期化するために、いくつかのReduxのアクションを書く次に

class Startup extends Component { 
    static propTypes = { 
    connection: PropTypes.object 
    } 
    componentDidMount() { 
    this.props.actions.initialiseConnection(); 
    } 
    render() { 
    return this.props.connection 
     ? this.props.children 
     : (<p>Loading...</p>); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    connection: state.connection 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { 
    actions: bindActionCreators(Actions, dispatch) 
    }; 
} 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(Startup); 

を。治療をしなさい。

0

似ていますが、上記の代替(これが唯一反応させ、ルータのV3で動作するように見える):

Routes.js

import React from 'react'; 
import { Route, IndexRoute } from 'react-router'; 

import App from '../components/App'; 
import Home from '../views/Home'; 
import OnLoadAuth from '../containers/app/OnLoadAuth'; 

const routes = (
    <Route path="/" component={OnLoadAuth(App)}> 
    <IndexRoute component={Home} /> 
    {* Routes that require authentication *} 
    </Route> 
); 

export default routes; 

OnLoadAuth.js

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 

import { authenticateUser, fetchingUser } from '../../actions/AuthActionCreators'; 
import Spinner from '../../components/loaders/Spinner'; 

export default App => { 
    class OnLoadAuth extends Component { 
    componentDidMount =() => this.props.authenticateUser(); 

    render() { 
     return (this.props.isLoading === undefined || this.props.isLoading) 
       ? return <Spinner />; 
       : return <App {...this.props} />; 
    } 
} 

return connect(
    state => ({ isLoading: state.auth.fetchingUser }), 
     { authenticateUser, fetchingUser } 
    )(OnLoadAuth); 
}; 
関連する問題