Второй вызов действия с использованием старых данных магазина - PullRequest
0 голосов
/ 14 июля 2020

Я новичок в Javascript и Reactjs. Я пытался вызвать несколько действий при нажатии кнопки. Первое действие обновляет данные хранилища, а второе действие использует эти обновленные данные хранилища для вызова API.

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

Моя структура кода примерно такая

import React from 'react';
import {connect} from 'react-redux';
import {changeData,callApiAction} from './actions.js';

const ParentComponent = props => {

    <Button onClick={async () => {
        await props.changeData(props.storeData);    
        await props.callApiAction(props.storedata); 
    }}>
    Click Me!
    </Button>
}

const mapStateToProps = state => {
    return { storeData : state.storeData }
}

export default connect(mapStateToProps, {changeData, callApiAction})(ParentComponent);

Действия. js файл похож на

export const changeData = (storeData) = async dispatch => {

    // modify Store data

    await dispatch({
        type: UPDATE_STORE,
        payload: {
        newStoreData: storeData
        }       
    })
} 

export const callApiAction = (storeData) = async dispatch => {

    try{
        // call API witht the storeData

    } catch(e) {
        // show Error Dialog
    }
}

1 Ответ

0 голосов
/ 14 июля 2020

Мое единственное объяснение того, почему это могло произойти, связано с тем, как Redux использует поток данных. Хранилище Redux обрабатывает действия синхронно, однако вы используете их с синтаксисом async / await. На мой взгляд, это может быть связано с этим. Так как это исправить? В документации Redux рекомендуется использовать промежуточное ПО. Один из самых популярных пакетов для этого - redux-thunk. Redux-thunk действительно прост в использовании.

Добавьте в свой магазин следующие строки:

// ... other imports
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";

const middlewares = [thunk];

// Find your createStore function 
const store = createStore(
  rootReducer, // your root reducer
  compose(applyMiddleware(...middlewares)) // add this line of configuration
);

Теперь, чтобы использовать преобразователи в redux:

// Remove the async await syntax from synchronous actions
export const changeData = (storeData) = dispatch => {

    // modify Store data

    dispatch({
        type: UPDATE_STORE,
        payload: {
           newStoreData: storeData
        }       
    })
}


// New action for your api call
export const callApiAction = () => {
  return async (dispatch, getState) => {
    dispatch(changeData());
    const { storeData } = getState().reducerName // Replace with your reducer name where storeData is
    try {
      // call the API
      // Dispatch a success action to update the store or some other logic
   } catch(err) {
      // Here you can dispatch a failure action
   }
};
 

Затем ваш компонент React вы можете просто использовать await callApiAction() без каких-либо аргументов, потому что он получает их прямо из магазина и опускает другой вызов changeData().

Изменить: вы можете видеть преобразователи как просто создатели действий или функции, которые возвращают другие функции. Подробнее о redux-thunk: https://github.com/reduxjs/redux-thunk

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...