在这篇文章中,我们将研究如何将 redux 与 React JS 或 Next JS 集成,以实现 Web 应用程序的全局状态管理。随着应用程序的增长,我们将希望在应用程序之间共享状态。为了做到这一点,我们可以使用一个名为 redux 的状态管理库来管理应用程序中的状态。那么让我们深入探讨一下。
首先,让我们创建一个 React 项目。
npx create-react-app redux-tutorial
cd redux-tutorial
安装必要的库。
npm i react-redux redux redux-thunk
学习redux的时候有两件事要做。
- 理解概念(以理论方式),
- 使用hooks在我们的应用程序中实现 redux(如果使用功能组件)
现在让我们看看使用 redux 的概念方面。Redux 有 4 个与之相关的术语。
- Actions
- Types
- Reducers
- Store
Store用于存储全局级别的状态。
Reducers是帮助改变状态的函数。
Actions是用来调用Reducers来改变状态的辅助函数。
Types是我们为在 redux 环境中进行状态更改而指定的名称。
现在我们将创建文件夹和所需的文件以将 redux 集成到我们的应用程序中。
创建如下所示的文件夹结构。
现在我们将在这里使用 redux 制作一个小型 TODO 应用程序。我们将把我们的reducers命名为 todoReducer (你可以将其命名为 userReducer 等任何名称)
我们将创建 2 个Types和 2 个Actions。Types是,
- ADD
- DELETE
和 2 个Actions,
- addTodoAction
- deleteTodoAction
(您可以根据需要命名操作和化简器,但我使用这种格式,效果很好。)
import { ADD_TODO, DELETE_TODO } from "../Types/TodoTypes";
export const addTodoAction = (data) => {
return {
type: ADD_TODO,
data: data,
};
};
export const deleteTodoAction = (data) => {
return {
type: DELETE_TODO,
data: data,
};
};
现在让我们转到 todoReducer 文件并复制粘贴以下代码。
import { ADD_TODO, DELETE_TODO } from "../Types/TodoTypes";
const initialState = {
todos: [{ name: "Redux", id: 1 }],
};
export const TodoReducers = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return { ...state, todos: [...state.todos, action.data] };
case DELETE_TODO:
return {
...state,
todos: state.todos.filter((item) => item.id !== action.data),
};
default:
return state;
}
};
那么这是怎么回事呢?
我们使用了一个 switch case 语句来处理我们创建的 2 种Types并更新 TODOS 的状态。因此,当我们调用带有Types的操作时,switch case 语句有条件地查看可以 ADD 或 DELETE 的类型,并执行必要的状态更改。
例如,在 ADD 类型中,如果从action中调用名为 ADD 的types,则状态会更新为在待办事项列表中添加该待办事项项目,这里是一个数组。
现在这可能看起来令人困惑,但 redux 一开始很难掌握,所以让我们看看实现。
转到 index.js 文件或应用程序的根文件,然后像这样添加 redux 包装器。
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux'
import { store } from './Redux/Reducer';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
这就是您在 React JS、Next JS 或任何其他前端框架中使用 redux 的方式,甚至可以在 React Native 应用程序中使用相同的代码。
现在让我们使用react-redux包提供的自定义hooks来获取存储在全局状态中的数据并对其进行修改。
因此,在下面的代码中,我们要做的是添加一个待办事项,并通过调用我们之前设置的actions来借助调度来删除它。然后我们将使用 useSelector 来获取数据并向用户显示待办事项。我们将使用映射函数,因为我们将待办事项状态初始化为数组。当用户按下提交按钮时,我们调用 addTodoAction 并添加待办事项,如果他按下删除按钮,我们会通过使用我们生成的唯一 ID 过滤待办事项来删除该待办事项。
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { addTodoAction, deleteTodoAction } from "./Redux/Actions/TodoActions";
function App() {
const [name, setName] = useState();
const dispatch = useDispatch();
const todoData = useSelector((state) =>state.TodoReducers);
return (
<div
style={{
margin: 200,
}}
>
<div>
<input
type="text"
value={name}
onChange={(e) => {
setName(e.target.value);
}}
/>
</div>
<button
onClick={() => {
const todo = { id: Math.random(), name: name };
dispatch(addTodoAction(todo));
setName("");
}}
>
Submit
</button>
{todoData?.todos?.map((item, key) => {
return (
<div key={item?.id}>
{key + 1} . {item?.name}{" "}
<div
onClick={() => {
dispatch(deleteTodoAction(item?.id));
}}
>
Delete
</div>
</div>
);
})}
</div>
);
}
export default App;
这就是创建 redux 文件夹结构,然后创建化reducers, actions, types并使用自定义挂钩全局修改和存储数据的方式。
除了本篇文章之外,我们还需要通过更多的实践或者查阅更多的资料去理解这些,因为他确实是一个比较难以理解的知识点或者实践!