状态未使用react redux thunk进行更新

时间:2018-02-19 16:28:41

标签: javascript reactjs redux react-redux redux-thunk

我使用redux并做出反应有点新鲜。我正在尝试使用redux进行一个简单的API调用,并让它在反应中呈现。我可以看到API调用在redux dev工具的有效负载中工作,但我似乎无法在`connect?中更新状态。

actions/index

import FilmAPI from '../api/api';

export const FETCH_FILMS = 'FETCH_FILMS';
export const RECEIVE_FILMS = 'RECEIVE_FILMS';

export const receiveFilms = (films) => {
  return {
    type: RECEIVE_FILMS,
    films
  };
}

    export const fetchFilmsRequest = () => {
  return dispatch => {
    return axios.get('https://www.snagfilms.com/apis/films.json?limit=10')
      .then(response => {
        dispatch(receiveFilms(response.data))
      })
  }
}

export default fetchFilmsRequest;

reducers/FilmReducer

import RECEIVE_FILMS from '../actions/index';

export function films (state = [], action) {
 switch (action.type) {
    case RECEIVE_FILMS:
      return [...state, action.films];
    default:
      return state;
  }
}

reducers/index

import { combineReducers } from 'redux';
import { films } from './FilmsReducer';

export default combineReducers({
  films,
});

containers/FilmListContainer

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchFilmsRequest } from '../actions';
import FilmList from '../components/FilmList'

class FilmListContainer extends Component {
  constructor(props) {
    super(props);
  }

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

  render() {
    return (
      <div>
        <FilmList films={this.props.films}/>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  films: state.films
})

export default connect(mapStateToProps, {fetchFilmsRequest: fetchFilmsRequest})(FilmListContainer);

configureStore.js

import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

export default function configureStore(initialState) {
    const composeEnhancers =
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
            window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
                // options like actionSanitizer, stateSanitizer
            }) : compose;

    const enhancer = composeEnhancers(
        applyMiddleware(thunk)
    );

    return createStore(
        rootReducer,
        initialState,
        enhancer
    );
}

如前所述,Redux DevTools在有效载荷中显示电影,但电影仍处于其状态0。有谁能指出我正确的方向?

4 个答案:

答案 0 :(得分:0)

您已经关闭了,您的行动需要通过调度您的减速器可以捕获的事件将数据发送到商店。这是使用调度对象上的type属性完成的。

https://redux.js.org/basics/actions

return fetch('https://www.snagfilms.com/apis/films.json?limit=10')
  .then(response => {
    dispatch({
      type: RECEIVE_FILMS,
      payload: response,
    })
  })

然后,您需要获取reducer中的数据并将其放入商店

export function films (state = [], action) {
  switch (action.type) {
    case RECEIVE_FILMS:
      return { 
        ...state,
        films: action.payload.films
      };
    default:
      return state;
  }
}

答案 1 :(得分:0)

只需发送已解决的fetch承诺的结果:

如果有效载荷是json,那么:

export const fetchFilmsRequest = () => {
  return dispatch => {
    return fetch('https://www.snagfilms.com/apis/films.json?limit=10')
      .then(response => response.json())
      .then(response => {
        dispatch({
          type: RECEIVE_FILMS,
          payload: response
        })
      })
  }

您的减速机需要略微修改为:

export function films (state = [], action) {
  switch (action.type) {
    case RECEIVE_FILMS:
      return [...action.payload]; // assuming response is jus array of films
    default:
      return state;
  }
}

答案 2 :(得分:0)

看起来你只需要使用命名导入而不是默认导出将动作类型常量导入reducer。

即。 import {RECEIVE_FILMS} from '../actions'而不是import RECEIVE_FILMS from '../actions'

答案 3 :(得分:0)

您可以通过订阅商店并使用store.getState()

来获取更新状态

步骤:

  1. 在组件类的构造函数中编写订阅函数。
  2. 通过store.getState()设置类的状态。

从“ ../js/store/index”导入商店;

class MyClass扩展了组件{

构造函数(属性,上下文){

 super(props, context);

 this.state = {

        classVariable: ''

 }
 store.subscribe(() => {

    this.setState({

    classVariable: store.getState().MyStoreState.storeVariable

    });

 });

}

}