我有一个Reaction Redux工具包切片,在我想要的地方:

  1. 更新我的状态
  2. 将此更新状态获取到我的后端

我想做这样的事情:

const sendStateToBackend = createAsyncThunk(
    '.../sendStateToBackend',
    async (state) => {
        const data = await ...
    }
)


createSlice({
    ...,
    reducers: {
        addTodo:(state, action) => {
            state.todos.push(action.payload)
            dispatch(sendStateToBackend(state)) // This is an Anti pattern???
        }
    },
    extraReducers(builder) {
        builder.addCase(sendStateToBackend.pending, (state) => {
            state.isLoading = true
        }

        builder.addCase(sendStateToBackend.fulfilled, (state, action) => {
            state.isLoading = false
        }
    }
})

在我的页面中.tsx:

const onSubmit = async (values) => {
    try {
        dispatch(addTodo(values))
        // Can I trigger another dispatch here? 
    } catch (error) {
        console.error('An error occurred while submitting the form: ', error)
    }
}

我怎样才能做到这一点呢?

推荐答案

您可以使用Redux工具包切片的extraReducers部分来处理由addTodo操作触发的API调用.当addTodo动作完成时,你应该让extraReducers来处理它,而不是在addTodo减速器内部调度sendStateToBackend动作.

下面是重构代码的方法:

1-从切片中的addTodo减速器中取出派单:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

const sendStateToBackend = createAsyncThunk('.../sendStateToBackend', async (state) => {
  // Implement your API call here and return the response data
  // For example, you might use fetch or axios to send the state to the backend
  // const response = await fetch('your-api-url', {
  //   method: 'POST',
  //   body: JSON.stringify(state),
  //   headers: {
  //     'Content-Type': 'application/json',
  //   },
  // });
  // const data = await response.json();
  // return data;
});

const todoSlice = createSlice({
  name: 'todo',
  initialState: { todos: [], isLoading: false },
  reducers: {
    addTodo: (state, action) => {
      state.todos.push(action.payload);
    },
  },
  extraReducers(builder) {
    builder
      .addCase(sendStateToBackend.pending, (state) => {
        state.isLoading = true;
      })
      .addCase(sendStateToBackend.fulfilled, (state, action) => {
        state.isLoading = false;
        // Do something with the response data from the backend if needed
        // const responseData = action.payload;
      });
  },
});

export const { addTodo } = todoSlice.actions;
export default todoSlice.reducer;

2-在您的page.tsx中,您可以在"onSubmit"函数中按顺序调度这两个操作:

import { useDispatch } from 'react-redux';
import { addTodo, sendStateToBackend } from './your-todo-slice';

const YourPageComponent = () => {
  const dispatch = useDispatch();

  const onSubmit = async (values) => {
    try {
      // Dispatch the addTodo action to update the state
      dispatch(addTodo(values));

      // Dispatch the sendStateToBackend action to send the updated state to the backend
      await dispatch(sendStateToBackend(values));
    } catch (error) {
      console.error('An error occurred while submitting the form: ', error);
    }
  };

  return (
    <div>
      {/* Your page content */}
    </div>
  );
};

export default YourPageComponent;

当调度addTodo操作时,它将更新Redux存储中的状态.然后,extraReducers部分将处理sendStateToBackend操作,在完成addTodo操作时进行API调用以将更新后的状态发送到后端.通过在onSubmit函数中使用await,您可以确保在继续其余代码之前完成API调用.

Javascript相关问答推荐

JS、C++和C#给出不同的Base 64 Guid编码结果

我不知道为什么我的JavaScript没有验证我的表单

每次子路由重定向都会调用父加载器函数

Cypress -使用commands.js将数据测试id串在一起失败,但在将它们串在一起时不使用命令有效

如何解决CORS政策的问题

将状态向下传递给映射的子元素

用JavaScript复制C#CRC 32生成器

将本机导航路由react 到导航栏中未列出的屏幕?

v—自动完成不显示 Select 列表中的所有项目

如何调用名称在字符串中的实例方法?

为什么useState触发具有相同值的呈现

未定义引用错误:未定义&Quot;而不是&Quot;ReferenceError:在初始化&Quot;之前无法访问';a';

Web Crypto API解密失败,RSA-OAEP

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

与svg相反;S getPointAtLength(D)-我想要getLengthAtPoint(x,y)

expo 联系人:如果联系人的状态被拒绝,则请求访问联系人的权限

按什么顺序接收`storage`事件?

每次重新呈现时调用useState initialValue函数

判断函数参数的类型

Reaction useState和useLoaderData的组合使用引发无限循环错误