【问题标题】:State not updating with react redux thunk状态未使用 react redux thunk 更新
【发布时间】:2018-02-19 16:28:41
【问题描述】:

我对使用 redux 和 react 有点陌生。我正在尝试使用 redux 进行简单的 API 调用并让它在反应中呈现。我可以看到 API 调用在 redux 开发工具的有效负载中工作,但我似乎无法让它更新可能在“连接?”中的状态。

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 的状态。谁能指出我正确的方向?

【问题讨论】:

  • 您找到解决方案了吗?刚接触 Redux 并撞到我的头

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


【解决方案1】:

您可以通过订阅商店获取更新状态并使用store.getState()

步骤:

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

从'../js/store/index'导入存储;

类 MyClass 扩展组件 {

构造函数(道具,上下文){

 super(props, context);

 this.state = {

        classVariable: ''

 }
 store.subscribe(() => {

    this.setState({

    classVariable: store.getState().MyStoreState.storeVariable

    });

 });

}

}

【讨论】:

    【解决方案2】:

    您已经接近了,您的操作需要通过调度您的减速器可以捕获的事件来将数据发送到商店。这是使用调度对象上的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;
      }
    }
    

    【讨论】:

    • 首先,谢谢!我已经尝试了您的建议,但不幸的是,仍然没有。 this.props.films 仍为 0。
    • 它会被添加到 Redux 商店吗?如果您还没有,请安装一个浏览器扩展程序,这对您调试有很大帮助
    • 我相信确实如此。我正在使用 Redux Devtools。它在有效载荷中显示数据,但电影似乎仍然没有填充。 this.props 返回{films: Array(0), fetchFilmsRequest: ƒ}
    【解决方案3】:

    看起来您只需使用命名导入而不是默认导出将动作类型常量导入减速器。

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

    【讨论】:

    • 换句话说,你的 reducer 正在被调度,但它永远不会落入那个 case 语句,因为它正在导入异步请求并将其与操作类型(一个字符串)进行比较。
    • 正如其他人所建议的那样,您需要将您的 receiveFilms 操作准确地发送到您有评论的地方。 dispatch(receiveFilms(response))
    • 我遇到了同样的问题,并且按照上述方式配置了所有内容。当我为当前用户获取时,我的状态会更新,但商店没有触发刷新。当我在 redux 中查看时,我会使用用户详细信息进行身份验证。
    【解决方案4】:

    只需像这样发送已解决的fetch promise 的结果:

    如果payload是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;
      }
    }
    

    【讨论】:

    • 谢谢!我已经尝试过这种方法并将电影数据放在有效负载中,但状态仍然没有更新。 this.props 返回{films: Array(0), fetchFilmsRequest: ƒ}
    • 它会进入你的减速器吗?你可以在那里记录有效载荷吗?你在哪里打电话给createStore
    • 我尝试记录有效载荷,它返回undefined?我会用我的createStore更新我的帖子。
    猜你喜欢
    • 2019-05-30
    • 1970-01-01
    • 2021-01-08
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    相关资源
    最近更新 更多