2016-06-27 5 views
4

私はこの問題を数週間は苦労しています。私は最終的にタオルを投げて、何か正しいことをしていないので、これについて助けを求めています。私はreduxとredux-thunkを使っているReact.jsアプリを持っています。私は単にデータのロードを開始するためにコンポーネントコンテナを取得しようとしていますが、データがフェッチ要求から戻ってくるまでレンダリングしません。私が知っているほどシンプルだと思う。ここで私がやったことです:redux-thunk:アクションクリエーターが完了するまでコンポーネントの実行を一時停止する

コンテナコンポーネント

'use strict'; 
import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { fetchActivePlayer } from '../actions/index'; 
import PlayerDetails from '../components/players/player-detail'; 
import Spinner from '../components/common/spinner/index'; 
import store from '../store'; 

export default class PlayerDetailContainer extends Component { 
    constructor(props) { 
     super(props); 
    } 

    componentWillMount() { 
     this.props.fetchActivePlayer(this.props.params.player_slug) 
    } 

    render() { 
     if (!this.props.activePlayer.activePlayer) { 
      return (
       <Spinner text="Loading..." style="fa fa-spinner fa-spin" /> 
      ); 
     } 

     return (
      <PlayerDetails 
       player={ this.props.activePlayer.activePlayer } 
      /> 
     ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
     activePlayer: state.activePlayer 
    } 
} 
export default connect(mapStateToProps, { fetchActivePlayer })(PlayerDetailContainer); 

アクションクリエーター

export function fetchActivePlayer(slug) { 
    return (dispatch, getState) => { 
     return axios.get(`${ROOT_URL}/players/${slug}`) 
     .then(response => { 
      dispatch({ 
       type: FETCH_ACTIVE_PLAYER, 
       payload: response 
      }) 
     }) 
     .catch(err => { 
      console.error("Failure: ", err); 
     });  
    }; 
} 

ストア

'use strict'; 
import React from 'react'; 
import { browserHistory } from 'react-router'; 
import { createStore, applyMiddleware } from 'redux'; 
import { routerMiddleware } from 'react-router-redux'; 
import thunk from 'redux-thunk'; 
import promise from 'redux-promise'; 
import reducers from './components/reducers/index'; 

const createStoreWithMiddleware = applyMiddleware(
    thunk, 
    promise, 
    routerMiddleware(browserHistory) 
) (createStore); 
export default createStoreWithMiddleware(reducers); 

ルートここ

export default (
<Route path="/" component={ App }> 
     <IndexRoute component={ HomePage } /> 
     <Route path="players/:player_slug" component={ PlayerContainer } /> 
     <Route path="/:player_slug" component={ PlayerContainer } /> 
    </Route> 
); 

はバージョンでは、私はすべてのために使用していますされています が反応= 0.14.7 反応-再来= 4.4.1 Reduxの-サンク= 0.5.3

ときIこれを実行すると、エラーは表示されませんが、アクション作成者が発砲しているのは明らかですが、作成者が終了するのを待つのではなく、コンポーネントコンテナが継続しています。私が言ったように、私は本当にシンプルなものを見逃していなければならないと確信していますが、それが何であるか把握できないようです。

ありがとうございます。どんな助けでも大歓迎です。

+0

あなたのスピナーは決して表示されないのですか?またはあなたのスピナーだけが表示されますか? – azium

+0

あなたの状態の形状を見ることができるようにあなたの質問に減速機を含めることができますか? –

+0

また、ここでいくつかの言語をクリアするために、コンポーネントの実行を一時停止することはありません。それはあなたの脳を一時停止させるようなものです。 UIは人生のような単なるストリームであり、現在の状態に基づいて異なるものをレンダリングするだけです。 – azium

答えて

5
  1. componentWillMountでのアクション(フェッチ)は非同期であり、コンポーネントは待機しません。
  2. 通常、データを取得するときに、取得プロセスのステータスを知りたいとします。エラーを表示するためにローダ、成功、失敗を表示するために、 "isfetching"のように。
  3. これらのステータスを使用して、アクションクリエーターが完了するまで、コンポーネントをロード/マウント/起動しないことができます。

したがって、あなたはそのようなあなたのReduxの部品気にいらを整理する必要があります。

状態

activePlayer:{ 
    data:data, 
    isFetching: true/false, 
    error:"" 
    } 

アクション

export const fetchActivePlayer = slug => dispatch =>{ 
    dispatch({ 
     type: 'FETCH_ACTIVE_PLAYER_REQUEST', 
     isFetching:true, 
     error:null 
    }); 

    return axios.get(`${ROOT_URL}/players/${slug}`) 
    .then(response => { 
     dispatch({ 
      type: 'FETCH_ACTIVE_PLAYER_SUCCESS', 
      isFetching:false, 
      payload: response 
     }); 
    }) 
    .catch(err => { 
     dispatch({ 
      type: 'FETCH_ACTIVE_PLAYER_FAILURE', 
      isFetching:false, 
      error:err 
     }); 
     console.error("Failure: ", err); 
    }); 

}; 

減速

const initialState = {data:null,isFetching: false,error:null}; 
export const actionPlayer = (state = initialState, action)=>{ 
    switch (action.type) { 
     case 'FETCH_ACTIVE_PLAYER_REQUEST': 
     case 'FETCH_ACTIVE_PLAYER_FAILURE': 
     return { ...state, isFetching: action.isFetching, error: action.error }; 

     case 'FETCH_ACTIVE_PLAYER_SUCCESS': 
     return { ...state, data: action.payload, isFetching: action.isFetching, 
       error: null }; 
     default:return state; 

    } 
}; 

、あなたのコンポーネントが、私はあなたのアプリケーションがどのように見えるか分からないこの(打ち)

class PlayerDetailContainer extends Component { 
    componentWillMount() { 
     this.props.fetchActivePlayer(this.props.params.player_slug) 
    } 
    render() { 
     if (this.props.isFetching) { 
      return <Spinner text="Loading..." style="fa fa-spinner fa-spin" /> 

     }else if (this.props.error) { 
      return <div>ERROR {this.props.error}</div> 
     }else { 
      return <PlayerDetails player={ this.props.data } /> 
     } 
    } 
} 
const mapStateToProps = state =>({ 
     isFetching: state.activePlayer.isFetching, 
     data: state.activePlayer.data, 
     error: state.activePlayer.error, 
}) 

のように見えるかもしれません。この例の目的は、アプローチを示すことです。

+0

ありがとうUtro。私はこれを試して、あなたに戻ってきます。 –

+0

@LeachyPeachyはあなたのためにその仕事をしましたか? –

関連する問題