2016-06-27 3 views
4

Я боролся с этой проблемой уже несколько недель. Я, наконец, бросаю полотенце и прошу о помощи, потому что я явно не делаю что-то правильно. У меня есть приложение React.js, которое использует redux и redux-thunk. Я просто пытаюсь заставить свой Контейнер компонентов инициировать загрузку данных, но не отображать до тех пор, пока данные не вернутся из запроса на выборку. Кажется достаточно простым, я знаю. Вот что я сделал: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 перевождь-преобразователь = 0.5.3

Когда я запустите это, я не получаю никаких ошибок, но ясно, что мой создатель действия увольняется, но контейнер компонентов продолжается, а не ждет завершения создания. Как я уже сказал, я уверен, что мне нужно пропустить что-то очень простое, но я не могу понять, что это такое.

Заранее спасибо. Любая помощь будет принята с благодарностью.

+0

Вы имеете в виду, что ваш спиннер никогда не показывает? Или показывает только ваш прядильщик? – azium

+0

Можете ли вы включить редуктор в свой вопрос, чтобы мы могли видеть вашу форму состояния? –

+0

Кроме того, чтобы прояснить какой-либо язык здесь, вы никогда не приостанавливаете выполнение компонента. Это похоже на то, чтобы приостановить ваш мозг. Пользовательский интерфейс - это просто постоянный поток, такой как жизнь, вы просто визуализируете разные вещи, основываясь на том, что такое текущее состояние. – azium

ответ

5
  1. Ваше действие (выборка) в компонентеWillMount является асинхронным, компонент не будет ждать.
  2. Обычно, когда вы извлекаете некоторые данные, вы хотите узнать о статусах процесса выборки. например, «isfetching», чтобы показать загрузчик, успех и неудачу, чтобы показать ошибку.
  3. Вы можете использовать эти статусы, чтобы не загружать/монтировать/запускать компонент, пока Action Creator не завершится.

Таким образом, вы должны организовать свою Redux часть Somthing так:

состояния

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

Спасибо Утро. Я попробую это и вернусь к вам. –

+0

@LeachyPeachy сделал это для вас? –

Смежные вопросы