我们将一步一步通过创建一个简单的项目来学习如何使用 Redux Toolkit、React-Redux 和 React,并模拟从 https://jsonplaceholder.typicode.com/users/1
获取数据的异步请求。我们将构建一个简单的用户信息显示应用。
第1步:创建React应用
首先,你需要安装 Node.js 和 npm(如果还没有安装的话)。接着,使用 create-react-app
创建一个新的 React 应用。
npx create-react-app redux-example
cd redux-example
第2步:安装依赖
在你的项目目录中,安装 @reduxjs/toolkit
、react-redux
以及 axios
(用于网络请求):
npm install @reduxjs/toolkit react-redux axios
第3步:设置Redux Store
- 创建Redux store:在
src
目录下创建一个app
目录,并在其中创建一个store.js
文件:
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../features/user/userSlice';
export const store = configureStore({
reducer: {
user: userReducer,
},
});
- 配置
Provider
:修改src/index.js
文件来提供 Redux store:
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { store } from './app/store';
import { Provider } from 'react-redux';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
第4步:创建Redux Slice
https://jsonplaceholder.typicode.com/users/1
返回内容
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}
在 src
目录下创建一个 features
目录。接着,创建一个 user
目录并在其中创建 userSlice.js
:
// src/features/user/userSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
// 定义异步thunk
export const fetchUser = createAsyncThunk('user/fetchUser', async (arg, { rejectWithValue }) => {
// arg 参数代表触发这个异步 thunk action 时传递给它的参数。
// 这意味着,当你调用这个由 createAsyncThunk 创建的异步 action 时,
// 你可以传递一些数据给它,这些数据通过 arg 参数在 thunk 函数内部可访问。 dispatch(fetchUser(1));
await new Promise((resolve) => setTimeout(resolve, 2000));
// 假设有一个 20% 的概率请求失败
const shouldFail = Math.random() < 0.2;
if (shouldFail) {
// 你可以在这里自定义错误信息
return rejectWithValue('Network request failed');
}
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
return response.data;
} catch (error) {
// 如果axios请求失败,也返回一个自定义的错误
return rejectWithValue(error.response.data || 'Network error occurred');
}
});
// 创建slice
export const userSlice = createSlice({
name: 'user',
initialState: {
entity: {},
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.entity = action.payload;
state.status = 'succeeded';
})
.addCase(fetchUser.rejected, (state) => {
state.status = 'failed';
});
},
});
export default userSlice.reducer;
第5步:在React组件中使用Redux
- 创建一个组件来显示用户信息。在
src
目录下创建一个features
目录(如果还没有),并在其下创建一个user
目录。在user
目录中,创建一个UserDisplay.js
组件:
// src/features/user/UserDisplay.js
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUser } from './userSlice';
export function UserDisplay() {
const user = useSelector((state) => state.user.entity);
const status = useSelector((state) => state.user.status);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchUser());
}, [dispatch]);
return (
<div>
{status === 'loading' && <p>Loading...</p>}
{status === 'succeeded' && (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
</div>
)}
{status === 'failed' && <p>Error fetching user.</p>}
</div>
);
}
- 在
App.js
中使用此组件:
// src/App.js
import React from 'react';
import { UserDisplay } from './features/user/UserDisplay';
function App() {
return (
<div className="App">
<header className="App-header">
<UserDisplay />
</header>
</div>
);
}
export default App;
这样,你就创建了一个简单的 React 应用,它使用 Redux Toolkit 来管理应用状态,并通过异步 thunk fetchUser
从远程 API 获取用户数据。
第6步:运行你的应用
现在,你可以运行你的应用来看到它的工作情况:
npm start
这将启动开发服务器,并在浏览器中打开你的应用。你应该能看到应用正在加载用户数据,然后显示该数据。
优化和代码风格
为了保证代码的可维护性和可读性,以下是一些推荐的最佳实践:
- 组织文件结构:我们将代码组织成
app
,features
等目录,这有助于保持项目的清晰和模块化。features
目录按功能(或“特性”)组织代码,每个功能有自己的 slice 和组件。 - 使用异步 thunk 进行数据获取:Redux Toolkit 的
createAsyncThunk
允许你轻松处理异步逻辑,并将结果分派到你的 store。这使得管理复杂的状态更加简单。 - 使用 React-Redux 的 Hooks:
useSelector
和useDispatch
Hooks 让你能够在组件中轻松访问 Redux store 的状态和分派 action,无需高阶组件或其他连接逻辑。
总结
通过这个示例,你学会了如何使用 Redux Toolkit 和 React-Redux 在 React 应用中管理状态,包括如何发起异步请求并处理结果。这只是 Redux 世界的入门级示例。随着你深入学习,你将会遇到更复杂的状态管理场景,Redux Toolkit 提供了强大的工具和方法来帮助你高效地解决这些问题。