Nikulio
@Nikulio
NaN !== NaN

Почему возникает Actions must be plain objects без ReduxThunk?

Всем привет
Такой AC для обработки асинхронного запроса :

export const searchAction = (val:string) => async dispatch => {
	const root:string = "https://images-api.nasa.gov/";
	const res = await axios.get(`${root}/search?q=${val}`);
	return dispatch({
		type: consts.SEARCH_INIT,
		payload: res
	})
};


Ошибка : Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
Но ведь я возвращаю обычный объект в переменной res. Почему тогда код не работает без ReduxThunk?
Спасибо
  • Вопрос задан
  • 13094 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Потому что redux-thunk это middleware и если бы вы заглянули в его исходники(всего 14 строк), то вы бы увидели, что он перехватывает и вызывает функции, передавая в них нужные аргументы и возвращает результат, не предавая его дальше. Без него их перехватывать нечему и они попадают туда куда не должны попадать и провоцируют ошибку, так как Redux без мiddleware на вход в dispatch принимает только объекты, о чем и говорится в тексте ошибки, которую вы получаете.

Возвращаемое значение(return) в асинхронных действиях используется только вами, его возвращает вызов dispatch. В редьюсеры, как было озвучено выше, оно не попадает.
Так как возвращается Promise, его можно использовать как-то так:
Ваш Async action:
export const asyncAction = (...someArgs) => async dispatch => {
  const res = await someAsyncCall(...someArgs);
  dispatch({ type: SOME_ACTION_TYPE, payload: res });

  return res;
};

Использование в коде(явный пример с dispatch):
componentDidMount() {
  const { dispatch } = this.props;

  dispatch(asyncAction(...optionalArgs)).then(result => doSomething(result));
}

То же самое с проброской async action через connect:
componentDidMount() {
  const { asyncAction } = this.props;

  asyncAction(...optionalArgs).then(result => doSomething(result));
}


Вообще, для использования then значение из асинхронной функции возвращать совсем не обязательно и такой код тоже будет прекрасно работать:
export const asyncAction = (...someArgs) => async dispatch => {
  const res = await someAsyncCall(...someArgs);
  dispatch({ type: SOME_ACTION_TYPE, payload: res });
};

Использование в коде(явный пример с dispatch):
componentDidMount() {
  const { dispatch } = this.props;

  dispatch(asyncAction(...optionalArgs)).then(() => doSomething());
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы