React Redux从JSON Server异步拉取数据报错:'customers未定义'求助
Redux结合JSON Server实现数据拉取及CRUD的正确方式
错误原因
你当前代码里的initialState: { value: customers }会报错,是因为customers变量仅在loadCustomers异步Thunk的内部定义,外部作用域根本不存在这个变量,所以触发了no-undef错误。
正确实现步骤及代码
1. 修正初始状态
初始状态需要包含数据存储、加载状态、错误信息三个核心字段,方便后续处理异步流程的UI反馈:
initialState: { data: [], // 存储从JSON Server拉取的客户数据 loading: false, // 标记数据加载状态 error: null // 存储加载或操作失败的错误信息 }
2. 完善异步逻辑并同步后端操作
将所有CRUD操作改为异步Thunk,确保本地状态与JSON Server数据同步,同时通过extraReducers处理异步操作的不同状态:
以下是完整的Slice代码:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; // 拉取客户数据的异步Thunk export const loadCustomers = createAsyncThunk("customers/load", async () => { const response = await fetch("http://localhost:8000/customers"); return await response.json(); }); // 添加客户的异步Thunk export const addCustomer = createAsyncThunk( "customers/add", async (newCustomer) => { const response = await fetch("http://localhost:8000/customers", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newCustomer), }); return await response.json(); } ); // 删除客户的异步Thunk export const deleteCustomer = createAsyncThunk( "customers/delete", async (customerId) => { await fetch(`http://localhost:8000/customers/${customerId}`, { method: "DELETE", }); return customerId; // 返回ID用于更新本地状态 } ); // 更新客户的异步Thunk export const updateCustomer = createAsyncThunk( "customers/update", async (updatedCustomer) => { const response = await fetch( `http://localhost:8000/customers/${updatedCustomer.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedCustomer), } ); return await response.json(); } ); export const customerSlice = createSlice({ name: "customers", initialState: { data: [], loading: false, error: null, }, extraReducers: (builder) => { // 处理拉取数据的三种状态 builder .addCase(loadCustomers.pending, (state) => { state.loading = true; state.error = null; }) .addCase(loadCustomers.fulfilled, (state, action) => { state.loading = false; state.data = action.payload; }) .addCase(loadCustomers.rejected, (state, action) => { state.loading = false; state.error = action.error.message || "加载客户数据失败"; }) // 处理添加客户 .addCase(addCustomer.fulfilled, (state, action) => { state.data.push(action.payload); }) // 处理删除客户 .addCase(deleteCustomer.fulfilled, (state, action) => { state.data = state.data.filter( (customer) => customer.id !== action.payload ); }) // 处理更新客户 .addCase(updateCustomer.fulfilled, (state, action) => { const targetIndex = state.data.findIndex( (customer) => customer.id === action.payload.id ); if (targetIndex !== -1) { state.data[targetIndex] = action.payload; } }); }, }); export default customerSlice.reducer;
3. 在组件中使用
在需要展示客户数据的组件中,通过useDispatch触发异步操作,useSelector获取状态:
import { useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { loadCustomers, addCustomer, deleteCustomer, updateCustomer } from "./customerSlice"; function CustomerTable() { const dispatch = useDispatch(); const { data: customers, loading, error } = useSelector((state) => state.customers); // 组件挂载时拉取数据 useEffect(() => { dispatch(loadCustomers()); }, [dispatch]); // 示例:添加客户 const handleAddCustomer = (newCustomer) => { dispatch(addCustomer(newCustomer)); }; // 其他删除、更新逻辑同理 if (loading) return <div>加载中...</div>; if (error) return <div>错误:{error}</div>; return ( <table> {/* 渲染客户表格逻辑 */} </table> ); } export default CustomerTable;
内容的提问来源于stack exchange,提问作者Kenertj
相关产品推荐
相关产品推荐

