【redux】redux-thunk 结合 Redux Toolkit 使用案例
如果不使用 createAsyncThunk 处理 AJAX 请求,你可以使用 Redux Toolkit 的其他功能来手动处理异步操作。你可以创建标准的 Redux action creators,并使用中间件(如 redux-thunk 或 redux-promise)来处理异步请求。下面是一个使用 redux-thunk 和 Redux Toolkit 的例子:
1. 安装 Redux 和 Redux Thunk
首先,安装 Redux 和 Redux Thunk:
npm install @reduxjs/toolkit react-redux redux-thunk
2. 配置 Store
在创建 Redux store 时应用 redux-thunk
中间件:
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import postsReducer from '../features/posts/postsSlice';
const store = configureStore({
reducer: {
posts: postsReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(thunk),
});
export default store;
3. 创建 Slice 和 Thunks
使用 createSlice
创建一个 slice 并定义异步操作的 thunks。
// src/features/posts/postsSlice.js
import { createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
const postsSlice = createSlice({
name: 'posts',
initialState: {
posts: [],
status: 'idle',
error: null,
},
reducers: {
fetchPostsStart(state) {
state.status = 'loading';
},
fetchPostsSuccess(state, action) {
state.status = 'succeeded';
state.posts = action.payload;
},
fetchPostsFailure(state, action) {
state.status = 'failed';
state.error = action.payload;
},
},
});
// 创建 actions
export const { fetchPostsStart, fetchPostsSuccess, fetchPostsFailure } = postsSlice.actions;
// 异步 thunk action
export const fetchPosts = () => async (dispatch) => {
dispatch(fetchPostsStart());
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
dispatch(fetchPostsSuccess(response.data));
} catch (error) {
dispatch(fetchPostsFailure(error.message));
}
};
export default postsSlice.reducer;
4. 创建 React 组件并连接 Redux
使用 React-Redux 的 useDispatch
和 useSelector
钩子来连接 Redux store,并在组件中触发异步请求。
// src/features/posts/PostsList.js
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchPosts } from './postsSlice';
const PostsList = () => {
const dispatch = useDispatch();
const posts = useSelector((state) => state.posts.posts);
const status = useSelector((state) => state.posts.status);
const error = useSelector((state) => state.posts.error);
useEffect(() => {
if (status === 'idle') {
dispatch(fetchPosts());
}
}, [status, dispatch]);
if (status === 'loading') return <p>Loading...</p>;
if (status === 'failed') return <p>Error: {error}</p>;
return (
<div>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
export default PostsList;
5. 连接 Redux Provider
确保你的应用使用 Provider
组件来传递 Redux store。
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './app/store';
import PostsList from './features/posts/PostsList';
const App = () => (
<Provider store={store}>
<PostsList />
</Provider>
);
ReactDOM.render(<App />, document.getElementById('root'));
总结
通过使用 redux-thunk
,你可以轻松地处理 Redux 中的异步操作。主要步骤包括:
- 安装和配置中间件:在 Redux store 中应用
redux-thunk
中间件。 - 创建 slice 和 thunks:使用
createSlice
创建一个 slice,并定义处理异步操作的 thunk。 - 在 React 组件中使用 Redux:使用
useDispatch
和useSelector
钩子来连接 Redux store,并触发异步请求。 - 连接 Redux Provider:确保你的应用使用
Provider
组件来传递 Redux store。
通过这些步骤,你可以灵活地在 Redux 中处理 AJAX 请求,简化异步逻辑,提高代码的可读性和维护性。