Redux Toolkit includes these APIs:
ๅฆๆ็จ@reduxjs/toolkitไพๅฏซredux๏ผๅฏ็ดๆฅไฝฟ็จไปฅไปฅไธredux-thunk็ๅ่ฝ(ๅพไธ็)
็ถไฝ ๆฒๆ็จ@reduxjs/toolkit๏ผๅฎ็ดไฝฟ็จ redux
้่ฆ่ช่ก npm i redux-thunk
ๅ ้ฒ configureStore ็ middleware ่ฃก
ๅฏไปฅ่ฎๆ่ฎไฝ ๅ่ช่ก่จญๅฎไธญ็action่ฃก๏ผๅฏdispatchๅค้action๏ผ่ฎๅพๅจaction่ฃกๅฏไปฅ็ ง่ฆๅไฝฟ็จ dispatch ๅ getState ็ถๅๆธ็จ
When this function is passed to dispatch
, the thunk middleware will intercept it,
and call it with dispatch
and getState
as arguments.
This gives the thunk function the ability to run some logic, and still interact with the store.
stackoverflow( basic ):
โโโโimport { createStore, applyMiddleware } from 'redux'
โโโโimport thunk from 'redux-thunk'
โโโโconst store = createStore(
โโโโ reducer,
โโโโ applyMiddleware(thunk)
โโโโ)
โโโโ// It still recognizes plain object actions
โโโโstore.dispatch({ type: 'INCREMENT' })
โโโโ// But with thunk middleware, it also recognizes functions
โโโโstore.dispatch(function (dispatch) {
โโโโ // ... which themselves may dispatch many times
โโโโ dispatch({ type: 'INCREMENT' })
โโโโ dispatch({ type: 'INCREMENT' })
โโโโ dispatch({ type: 'INCREMENT' })
โโโโ setTimeout(() => {
โโโโ // ... even asynchronously!
โโโโ dispatch({ type: 'DECREMENT' })
โโโโ }, 1000)
โโโโ})
example (react-redux):
store.js
โโโโimport { createStore, applyMiddleware } from "redux";
โโโโimport { composeWithDevTools } from "redux-devtools-extension";
โโโโimport thunk from "redux-thunk";
โโโโimport rootReducer from "./reducers";
โโโโconst initialState = {};
โโโโconst middleware = [thunk];
โโโโconst store = createStore(
โโโโ rootReducer,
โโโโ initialState,
โโโโ composeWithDevTools(applyMiddleware(...middleware))
โโโโ);
โโโโexport default store;
component
โโโโimport React, { useEffect } from 'react';
โโโโimport { useDispatch } from 'react-redux';
โโโโimport { getOrderDetails } from '../actions/orderActions';
โโโโconst OrderScreen = ({ match }) => {
โโโโ const orderId = match.params.id;
โโโโ const dispatch = useDispatch();
โโโโ useEffect(() => {
โโโโ dispatch(getOrderDetails(orderId));
โโโโ }, [dispatch, orderId]);
โโโโ
โโโโ return ( ... )
โโโโ }
action
โโโโimport axios from 'axios';
โโโโimport {
โโโโ ORDER_DETAILS_REQUEST,
โโโโ ORDER_DETAILS_SUCCESS,
โโโโ ORDER_DETAILS_FAIL,
โโโโ} from '../constants/orderConstants';
โโโโ
โโโโexport const getOrderDetails = (orderId) => async (dispatch, getState) => {
โโโโ try {
โโโโ dispatch({ type: ORDER_DETAILS_REQUEST });
โโโโ const {
โโโโ userLogin: { userInfo },
โโโโ } = getState();
โโโโ const config = {
โโโโ headers: {
โโโโ Authorization: `Bearer ${userInfo.token}`,
โโโโ },
โโโโ };
โโโโ const { data } = await axios.get(`/api/orders/${orderId}`, config);
โโโโ dispatch({ type: ORDER_DETAILS_SUCCESS, payload: data });
โโโโ } catch (err) {
โโโโ dispatch({
โโโโ type: ORDER_DETAILS_FAIL,
โโโโ payload:
โโโโ err.response && err.response.data.message
โโโโ ? err.response.data.message
โโโโ : err.message,
โโโโ });
โโโโ }
โโโโ};
With a plain basic Redux store, you can only do simple synchronous updates by dispatching an action. Middleware extends the store's abilities, and lets you write async logic that interacts with the store.
Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.
redux-thunk is the most commonly used middleware for working with both synchronous and async logic outside of components
With Redux Thunk action creators can dispatch the result of other action creators and not even think whether those are synchronous or asynchronous: