Redux thunk的用途是什么
Redux 是一个状态管理工具,用于存储React应用程序中不同变量的状态。它通过集中管理应用程序状态,简化了复杂的React应用程序开发。你可以在这里了解更多有关Redux的信息。Redux支持中间件,中间件函数在触发动作和到达reducer之间运行。Redux中间件可用于日志记录、路由、异步操作等功能。
在本教程的范围内,我们将重点关注redux中的一个中间件叫做thunk。它允许我们从redux动作中返回函数而不是对象。纯redux不能在动作函数中执行复杂逻辑,你只能通过触发动作进行简单的同步更新。这个中间件扩展了它的功能,允许你编写与存储库交互的复杂逻辑。只有在返回函数时,thunk才会介入动作。Thunk允许我们手动触发动作,这使我们有能力在触发动作之前合并一些逻辑或运行一些异步代码。从动作中返回的函数被称为thunk函数,它接收两个参数:
1. dispatch: 这是一个用于触发动作的方法,可以被reducer接收。
2. getState: 它在thunk函数内部提供对存储库的访问权限。
thunk函数可以包含任意的逻辑,同步或异步,并且可以随时调用dispatch或getState。在进一步讨论之前,让我们了解一下带有和不带有thunk的redux流程之间的区别。
不带thunk的Redux流程:
Redux使用Thunk的流程:
使用Thunk设置Redux:
步骤1: 要使用thunk设置redux,我们将从创建一个react应用程序开始,并安装所有所需的依赖项。运行以下命令来创建一个新的react应用程序。
npx create-react-app myapp
步骤2: 在代码编辑器中打开您的项目,并安装所有所需的包:redux,react-redux和redux-thunk。
npm install redux react-redux redux-thunk
现在,在根目录下创建两个文件: actions.js 和 reducers.js.
以下是更新后的项目结构:
现在我们将创建一些操作和reducer根据这些操作与存储进行交互。
我们将创建两个actions, deleteData 是一个普通的action创建者,它不包含任何复杂或异步逻辑,因此thunk不会干扰它的执行。 addData action创建者包含异步逻辑,因此我们返回一个函数(thunk函数),该函数在从API获取数据时调用dispatch。(对于本教程,我们使用 JSONPlaceholderAPI ,你可以在这里了解更多信息。)然后在app.js文件中,我们添加按钮来调度操作和显示获取到的数据。
/action.js
// This is a synchronous action, hence
// thunk will not interfere.
export const deleteData = ()=>{
return ({
type : 'DELETE_DATA'
})
}
// This function includes some async logic,
// hence we can dispatch action manually
export const addData = ()=>{
// Thunk Function
return async (dispatch,getState)=>{
// Fetching results from an API : asynchronous action
const response = await fetch(
'https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
// Dispatching the action when async
// action has completed.
dispatch({
type : 'ADD_DATA',
payload : data
});
}
}
在这里,我们将创建reducers根据这些操作更新状态,并导出这些reducers来创建一个state。
/reducers.js
const { combineReducers } = require("redux");
const INITAL_STATE = {
todo : null
}
const dataReducer = (state=INITAL_STATE, action)=>{
switch(action.type) {
case 'ADD_DATA' : return {...state, todo : action.payload};
case 'DELETE_DATE' : return INITAL_STATE;
default : return state;
}
}
const reducers = combineReducers({
data : dataReducer
})
export default reducers
首先我们会清理一些样板代码,然后使用thunk中间件创建一个store。Provider函数将整个应用程序的状态集中在一起。
/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { applyMiddleware, createStore } from "redux";
import reducers from "./reducers";
import thunk from "redux-thunk";
import { Provider } from "react-redux";
// Create store with the reducers and
// apply thunk as a middleware
const store = createStore(reducers, applyMiddleware(thunk));
const root = ReactDOM.createRoot(
document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
我们首先导入所有的 actions 和 hooks,然后使用 useDispatch hook来派发 actions,使用 useSelector hook来访问存储中的数据。我们添加了两个按钮来调用处理函数 handleAddData 和 handleDeleteData,它们会派发它们各自的 actions。
/app.js
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { addData, deleteData } from "./actions";
const App = () => {
const dispatch = useDispatch();
// Selects the state value from the store.
const todo = useSelector((state) => state.data.todo);
// Dispatches action to add the data
const handleAddData = ()=>dispatch(addData());
// Dispatches action to delete the data.
const handleDeleteData = ()=>dispatch(deleteData());
return (
<div>
<button onClick={handleAddData}>Add Data</button>
<button onClick={handleDeleteData}>Delete Data</button>
{todo && <div>{JSON.stringify(todo)}</div>}
</div>
);
};
export default App;
输出: