Redux-Thunk - как ждать завершения действия создателя - PullRequest
0 голосов
/ 15 октября 2018

У меня есть создатель этого действия:

type LoadOpenRequestsResult = ThunkAction<
  Promise<void>,
  IRootState,
  undefined,
  LoadOpenRequestsActions
>;

export const loadOpenRequests: ActionCreator<LoadOpenRequestsResult> = () => {
  [...]
};

, и я использую его в своем компоненте так:

public componentDidMount() {
  this.props.loadOpenRequests();
}

И я подключаю свой компонент React, используя объектную версию mapDispatchToProps, какэто:

export default connect(
  mapStateToProps,
  { loadOpenRequests }
)(MaintenanceOpenListScreen);

Я хотел бы сделать что-нибудь, когда асинхронное действие закончено, что-то вроде этого:

public componentDidMount() {
  await this.props.loadOpenRequests();
  doSomethingWhenThisAsyncIsDone();
}

, но this.props.loadOpenRequests(); не является Обещанием.

Означает ли это, что я не могу использовать объектную версию mapDispatchToProps?

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Я нашел решение здесь: https://github.com/reduxjs/redux-thunk/issues/213#issuecomment-428380685

По сути, ответ - да, вы не можете использовать объектную версию mapDispatchToProps.Вы должны использовать версию функции так:

public componentDidMount() {
  this.props.loadOpenRequests().then(() => doSomethingWhenThisAsyncIsDone());
}

[...]

const mapDispatchToProps = (
  dispatch: ThunkDispatch<IRootState, undefined, Action>
) => ({
  loadOpenRequests: () => dispatch(loadOpenRequests()),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MaintenanceOpenListScreen);
0 голосов
/ 16 октября 2018

Ваш компонент будет отправлять действия, действие может быть функцией, если вы используете thunk.Это действие, которое является функцией, получит функцию отправки, где вы можете отправлять действия, чтобы указать, что вы начали, закончили или не смогли что-то сделать.

Поэтому, когда у вас есть промежуточное ПО thunk в вашем магазине, вы отправляете действие, котороефункция thunk будет вызывать эту функцию, предоставляя ей функцию диспетчеризации.

Пример функции thunk можно найти здесь

function incrementAsync() {//function that create the action
  return dispatch => {//action is a function receiving dispatch
    dispatch(loading());//added this to show multiple actions can be dispatched
    setTimeout(() => {
      dispatch(result({hello:"world"}));//result is now available
    }, 1000);
  };
}

Ваш редуктор может что-то выглядетьнапример:

(state,action)=>{
  if(action.type===LOADING){
    return {...state,loading:true};
  }
  if(action.type===RESULT){
    return {...state,loading:false,result:action.payload};
  }
  //if result does not indicate failure you may need a fail/error action
  //  to set loading false and a message indicating why it failed.
  return state;
}

Теперь вы можете использовать реквизиты для отображения результата / загрузки и отправки incrementAsync в ваш componentDidMount.

Вы можете использовать redux connect , чтобы сопоставить обработчики действий с диспетчеризацией и добавить создателей действий в реквизиты, чтобы вы могли легко отправлять их в свой компонент.

...