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: