调度操作后 Redux 状态未更新

Posted

技术标签:

【中文标题】调度操作后 Redux 状态未更新【英文标题】:Redux state not being updated after dispatched actions 【发布时间】:2019-12-04 23:02:20 【问题描述】:

调度操作后,我的 redux 状态未正确更新。我正在使用 reduxredux-thunk 调用 API 并将其保存到 redux 存储中。我的状态应该保存一个 JSON 文件,因为将使用大量 JSON 文件,并且似乎没有任何 JSON 文件存储到存储中。问题在底部解释了

这是我定义动作类型的types.js 文件:

export const FETCHING_REQUEST = "FETCHING_REQUEST";
export const FETCHING_SUCCESS = "FETCHING_SUCCESS";
export const FETCHING_FAILURE = "FETCHING_FAILURE";

下一个文件是我的appActions.js 文件,其中包含应用程序的某些操作。代码中的 cmets 来自另一个我从未删除过的 *** 问题。

import  FETCHING_SUCCESS, FETCHING_REQUEST, FETCHING_FAILURE  from "./types";

// Actions for the redux store

export const fetchingRequest = () => 
  return 
    type: FETCHING_REQUEST
  ;
;

export const fetchingSuccess = json => 
  return 
    type: FETCHING_SUCCESS,
    payload: json
  ;
;

export const fetchingFailure = error => 
  return 
    type: FETCHING_FAILURE,
    payload: error
  ;
;

// Function will not work in a component
// Maybe the issue is redux
// more likely to be the Fetch not working in this function
export const fetchData = url => 
  console.log("Should enter async dispatch");
  return async dispatch => 
    dispatch(fetchingRequest());
    try
      let response = await fetch(url);
      let json = await response.json();
      let dispatchChecker = dispatch(fetchingSuccess(json));
      console.log("JSON",json);
      //console.log(JSON.stringify(json, null, 2));
    catch(error)
      console.log("ERROR",error);
      dispatch(fetchingFailure(error));
    
  ;
;

在应用的组件中被调用时,只应调用fetchData

appReducer.js 文件

import 
  FETCHING_SUCCESS,
  FETCHING_REQUEST,
  FETCHING_FAILURE
 from "../actions/types";
import * as data from "./../../../../pickerdata.json"; // for debugging issues
import * as sample from "../../../../sampledata.json";
const initialState = 
  isFetching: false,
  errorMessage: "",
  articles: null
;

const appReducer = (state = initialState, action) => 
  switch (action.types) 
    case FETCHING_REQUEST:
      console.log("request from reducer");
      return  ...state, isFetching: true ;
    case FETCHING_FAILURE:
      console.log("failure from reducer");
      return  ...state, isFetching: false, errorMessage: action.payload ;
    case FETCHING_SUCCESS:
      console.log("success from reducer");
      return  ...state, isFetching: false, articles: action.payload ;
    default:
      return state;
  
;

export default appReducer;

创建商店的index.js

import  AppRegistry  from "react-native";
import App from "./App";
import  name as appName  from "./app.json";
import  Provider  from "react-redux";
import React,  Components  from "react";
import  createStore, applyMiddleware  from "redux";
import appReducer from "./src/data/redux/reducers/appReducer";
import thunk from "redux-thunk";

const store = createStore(appReducer, applyMiddleware(thunk));

store.subscribe(()=> 
  console.log("State Updated", store.getState());
)

console.log("Store", store.getState());
const AppContainer = () => (
  <Provider store=store>
    <App />
  </Provider>
);

AppRegistry.registerComponent(appName, () => AppContainer);

这是将我的商店连接到组件的代码

    const mapStateToProps = state => 
      return  response: state ;
    ;

    const mapStateToDispatch = dispatch => (
      fetchData: url => dispatch(fetchData(url))
    );

    export default connect(
      mapStateToProps,
      mapStateToDispatch
    )(Component);

这里的问题是 redux 状态没有被更新。使用控制台,我知道对 API 的 fetch 调用正在工作,因为 JSON 文件将显示在控制台中。使用store.subscribestore.getState,我可以看到存储没有改变,并且它与appReducer.js 文件中描述的初始状态相同。

例如在appActions.js 文件中的fetchData 方法中。第一个 dispatch 是到 fetchingRequest,redux store 应该是这样的

isFetching: true, errorMessage: "", articles: null 

却是这样

isFetching: false, errorMessage: "", articles: null

获取 API 成功后的下一个调度是 fetchingSuccess 操作,redux 存储应如下所示

isFetching: false, errorMessage: "", articles: JSONfile

但看起来像这样

isFetching: false, errorMessage: "", articles: null

【问题讨论】:

【参考方案1】:

在您的 types.js 文件中:

创建一个新类型 FETCHING_STATUS(例如)

在您的 fetchData 函数中:

替换dispatch(fetchingRequest());

dispatch(type: FETCHING_STATUS, payload:  isFetching: true );

dispatch(fetchingSuccess());替换为

dispatch(type: FETCHING_STATUS, payload: isFetching: false, articles: fetchingSuccess());

dispatch(fetchingFailed());替换为

dispatch(type: FETCHING_STATUS, payload:  isFetching: false, errorMessage: fetchingFailed());

在您的 appReducer.js 中:

import  combineReducers  from "redux";

function fetchingStatusReducer(state = , action) 
  switch (action.type) 
    case FETCHING_STATUS:
      return action.payload;
    default:
      return state;
  


export default combineReducers(
  fetchingStatus: fetchingStatusReducer
);

然后 store.getState().fetchingStatus 将根据需要更新

【讨论】:

我将如何引用状态以使用应用程序中的组件。例如,我会使用this.props.response.articles 来引用redux 状态,但是在您进行更改之后,这似乎不一样了。 在 mapStateToProps 函数中用 response: state.fetchingStatus 替换 response: state。这是引用 combineReducers 中的 fetchingStatus。

以上是关于调度操作后 Redux 状态未更新的主要内容,如果未能解决你的问题,请参考以下文章

Redux 状态在下一个 js 调度后不会改变

在通过动作调度进行状态更新后,在 React 中使用 Redux 执行函数?

调度操作时未调用redux connect mapStateToProps

Redux 存储在调度后不更新(异步数据加载)

动作调度不更新 Redux/React 中的状态

从非反应文件分派操作时 Redux 状态未更新