You need to enable JavaScript to run this app. React/Redux Toolkit:createAsyncThunk返回数据后如何同步更新组件状态
优惠活动
大模型
产品
解决方案
定价
更多

React/Redux Toolkit:createAsyncThunk返回数据后如何同步更新组件状态

Redux Toolkit环境下账户更新后状态不同步的问题解决

实际开发场景

开发中编写了用于更新数据库账户数据的异步请求,接口成功返回最新的账户结构化数据,返回结构示例:

{
  "Nome": "a",
  "Valor": 1700,
  "Historico": "teste",
  "Documento": 1,
  "DataEmissao": "2020-12-24T00:00:00.000Z",
  "DataVencimento": "2020-12-24T00:00:00.000Z",
  "createdAt": "2021-03-30T14:13:31.404Z",
  "id": "6063320bafd21c22e45f404c",
  "updatedAt": "2021-03-31T14:56:43.873Z",
  "__v": 0
}

存在的异常表现:

  • 接口请求完成后,Redux Store与关联组件不会用最新返回的数据覆盖旧值
  • 只有手动刷新页面、重新从数据库全量拉取列表数据时,页面才能显示最新的账户信息
  • 曾尝试使用createEntityAdapter实现状态更新,未达到预期效果

存在缺陷的原始代码

有问题的editCount异步thunk

export const editCount = createAsyncThunk('contas/editCount', async (data) => {
    const dados = data;
    axios.post('http://localhost:8080/api/teste/' + dados.documento, {
        Documento: dados.documento,
        Nome: dados.nome,
        Valor: dados.valor,
        Historico: dados.historico,
        DataEmissao: dados.dataEmissao,
        DataVencimento: dados.dataVencimento
    }).then(function (response) {
        console.log('teste', response.data)
        return response.data;
    }).catch(function (error) {
        console.log(error)
    })
})

原有slice的状态处理逻辑

const ContasReducer = createSlice({
    name: sliceName,
    initialState: {
        contas: [],
        status: null
    },
    reducers: {},
    extraReducers: (builder) => {
       builder.addCase(fetchCounts.fulfilled , (state, { payload }) => {
            state.contas = payload
            state.status = 'success'
        })
        builder.addCase(fetchCounts.pending , (state, action) => {
            state.status = 'Loading'
            state.contas = [{}]
        })
        builder.addCase(createAcount.fulfilled , (state, action) => {
            state = action.payload
            console.log('action payload', action.payload)
        })
        // 编辑账户的reducer处理逻辑存在错误
        builder.addCase(editCount.fulfilled , (state, action) => {
            state.conta = action.meta.arg;
            console.log('reducer',action.meta.arg)
        })
    }
})

组件内的保存触发逻辑

function SalvarDados() {
    Dispatch(
        editCount({
            documento: Documento,
            nome: Nome,
            valor: Valor,
            historico: Historico,
            dataEmissao: new Date(DataEmissao),
            dataVencimento: new Date(DataVencimento),
        })
    )
    props.CloseModal()
}

问题根因

createAsyncThunk的回调函数要求必须显式返回最终需要传递给reducer的内容,原有代码的两个核心缺陷:

  • 没有对axios.post的调用结果做前置await处理,内部.then回调里的return仅在自身作用域生效,外层异步函数实际没有返回任何值,导致thunk触发fulfilled动作时payload为空,根本拿不到接口返回的最新数据。之前尝试用createEntityAdapter也无法生效,本质也是因为thunk没有拿到正确的接口返回值,adapter没有可处理的源数据。
  • 原有editCount.fulfilled的状态更新逻辑,错误地把thunk接收的入参当成接口返回值,直接把入参赋值给state.conta,没有用到服务端返回的最新数据做覆盖。

修正后的实现

修复后的editCount thunk逻辑

通过await等待axios请求完成,显式将接口响应作为thunk的返回值,确保thunk能拿到正确的服务端数据:

export const editCount = createAsyncThunk('contas/editCount', async (data) => {
    const dados = data;
    const response = await axios.post('http://localhost:8080/api/teste/' + dados.documento, {
        Documento: dados.documento,
        Nome: dados.nome,
        Valor: dados.valor,
        Historico: dados.historico,
        DataEmissao: dados.dataEmissao,
        DataVencimento: dados.dataVencimento
    })
    return response.data;
})

修正后的状态同步逻辑

在editCount.fulfilled的回调中,通过接口返回的最新数据匹配列表中的对应账户,完成状态覆盖:

注:原参考修正代码中splice方法存在参数遗漏,完整的替换逻辑需要传入三个参数:目标索引、删除元素个数、用于替换的新元素,否则无法完成正确的列表更新。

builder.addCase(editCount.fulfilled , (state, {payload}) => {
    const [data] = payload;
    const contaIndex = state.contas.findIndex((obj) => obj.Documento === data.Documento)
    // 匹配到对应账户后替换为最新数据
    const updatedContas = [...state.contas]
    updatedContas.splice(contaIndex, 1, data)
    state.contas = updatedContas
})

内容的提问来源于stack exchange,提问作者Matheus Martins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 12:06:04