Не работает асинхронный action, Redux Thunk
Делаю запрос на сервер в асинхронном action. Но асинхронный action не запускается. Redux Thunk подключаю, @babel/polyfill подключаю. Хук useEffect срабатывает, а асинхронный action - нет. Синхронные actions работают нормально. Не понимаю, что я делаю не так?
index.js
import React from 'react'
import ReactDom from 'react-dom'
import {Provider} from 'react-redux'
import '@babel/polyfill'
import {createStore, applyMiddleware} from "redux"
import thunk from 'redux-thunk';
'import {reducer} from "./redux/reducer"
import { composeWithDevTools } from 'redux-devtools-extension'
import App from './App.js'
const store = createStore(reducer, composeWithDevTools(applyMiddleware(thunk)));
App.js
import React, {useEffect} from 'react'
import {fetchData} from "./redux/actions'
export default function () {
useEffect(() => {
fetchData();
}, []);
}
actions.js
export const fetchData = () => async dispatch => {
console.log('fetchData'); //не выводится
const res = await fetch("url");
dispatch({
type: FETCH_DATA,
payload: res.json()
});
};
Ответы (1 шт):
потому что когда Вы создали асинхронный action, то его нужно не просто вызывать, а диспатчить. например:
import React, {useEffect} from 'react'
import { useDispatch } from 'react-redux'; // подключаем хук для диспатча
import {fetchData} from "./redux/actions';
export default function () {
const dispatch = useDispatch(); // создаем сам диспатч
useEffect(() => {
dispatch(fetchData()); // вызываем fetchData уже как аргумент для dispatch
}, []);
}
наверное, стоит объяснить почему Вы ошиблись.
используя метод connect в классовых компонентах, Вы вызывали Ваши асинхронные actions без явного вызова в dispatch (то есть, просто fetchData()). это потому, что внутри connect сам уже оборачивал Ваши асинхронные actions. например:
const mapDispatchToProps = { fetchData };
это на самом деле сокращенный вариант для
const mapDispatchToProps = dispatch => ({
fetchData: () => {
dispatch(fetchData())
}
});
как Вы выдите, здесь connect будет за Вас оборачивать Ваш fetchData в dispatch.
в функциональных компонентах Вам нужно самому вручную это делать.
и заметил, что Вы внутри Вашего fetchData передаете в payload res.json(). это неправильно, так как res.json() возвращает промис. лучше сделать так:
export const fetchData = () => async dispatch => {
console.log('fetchData'); //не выводится
const res = await fetch("url");
const result = await res.json(); // распарсить значение здесь
dispatch({
type: FETCH_DATA,
payload: result // передать уже готовое значение
});
};