更新redux减速器中的状态

问题描述 投票:0回答:1

我有一个 nextjs 项目,我使用 redux 并且有减速器,我想在向服务器发送新的“任务”后更新其中一个减速器中的初始状态,因为它可以帮助我立即向用户显示新项目,但是当我尝试时更新它给我未定义

    import { createSlice } from "@reduxjs/toolkit";
import Cookies from "universal-cookie";
import { decode } from "jsonwebtoken";

const cookie = new Cookies();
const token = cookie.get("token");

export const initialState: any = {
  tasks: [],
  status: "idle",
};

// ========== Reducers ========== \\
// import { taskReducers } from "./reducers/task.reducer";

// ========== Thunks ========== \\
import { taskThunk } from "./thunks/task.thunk";
import { useGraphql } from "../../../helper/useGraphql";

const TaskSlice = createSlice({
  name: "task",
  initialState,
  reducers: {
    createTask: async (state, actions) => {
      const { id }: any = decode(token);

      try {
        const { taskName, taskTags } = actions.payload;

        const graphqlSchema = `
              mutation addTask($taskInput: TaskInput!) {
                  createTask(taskInput: $taskInput) {
                      _id
                      taskName
                      tags {
                          color
                          name
                      }
                  }
              }
          `;

        const variables = {
          taskInput: {
            taskName: taskName,
            tags: taskTags,
            userId: id,
          },
        };

        const { response } = await useGraphql(graphqlSchema, variables);

        const newElement = response.data.createTask;

        state.tasks = state.tasks.;

        return state;
      } catch (error) {
        console.log("Error in createTask reducer:", error);

        throw error;
      }
    },
  },
  extraReducers: (builder) => {
    builder.addCase(taskThunk.fulfilled, (state, actions) => {
      try {
        const tasks = actions.payload.getTasks;

        state.tasks = tasks;
        state.status = "success";
      } catch (error) {
        throw error;
      }
    });
  },
});

export const { createTask } = TaskSlice.actions;

export default TaskSlice.reducer;

这是我为了简化代码而构建的 useGraphql:

import axios from "axios";

export const useGraphql = async (schema: string, variables?: any) => {
  const graphqlSchema = {
    query: schema,
    variables: variables,
  };

  try {
    const sendRequest = await axios({
      url: "http://localhost:5000/",
      method: "POST",
      data: JSON.stringify(graphqlSchema),
      headers: {
        "Content-Type": "application/json",
      },
    });

    const response = sendRequest.data;

    return {
      response: response,
    };
  } catch (error) {
    throw error;
  }
};

这里我称之为函数

import { useState } from "react";

// =========== Components ========== \\
import Input from "../../../UIElements/input";
import Tags from "../../../UIElements/tags";
import Wrapper from "../wrapper.form";

// =========== Redux ========== \\
import { AppDispatch } from "../../../../redux/store";
import { useDispatch } from "react-redux";
import { createTask } from "../../../../redux/slices/tasks/index.slice";

const TaskCreatorForm = () => {
  const [taskName, setTaskName] = useState<String>("");
  const [taskTags, setTaskTags] = useState<Array<Object>>([]);

  const dispatch = useDispatch<AppDispatch>();

  const createTaskHandle = () => {
    const payload: any = {
      taskName,
      taskTags,
    };
    dispatch(createTask(payload));
  };

  return (
    <Wrapper admitFunction={createTaskHandle}>
      <Input
        placeholder="Task Name"
        type="text"
        label="Task Name"
        giveValue={setTaskName}
        requireSign={true}
      />
      <Tags
        giveValue={setTaskTags}
        coloration={true}
        placeholder="add tags"
        label="add Task"
      />
    </Wrapper>
  );
};

export default TaskCreatorForm;

这是一个包装器,我在其中传递 prop“admitfunction”

import { useContext } from "react";

// =========== Components =========== \\
import { PrimaryButton } from "../../UIElements";

// =========== context =========== \\
import { modalContext } from "../../../context/modal.context";

const Wrapper = ({ children, admitFunction }: any) => {
  const { toggleModal } = useContext(modalContext);

  return (
    <div className="flex flex-col gap-6">
      {children}
      <div className="flex items-center justify-end w-full gap-4">
        <PrimaryButton
          color="transparent"
          className="!text-black"
          onClick={() => toggleModal("taskcreator")}
        >
          Close
        </PrimaryButton>
        <PrimaryButton onClick={admitFunction} className="shadow-sm">
          admit
        </PrimaryButton>
      </div>
    </div>
  );
};

export default Wrapper;

我尝试过使用Google和chatGPT来解决这个问题,但没有成功

redux next.js reduce
1个回答
0
投票

Reducer 函数是纯函数,同步函数。在异步操作中完成工作并分派操作来更新存储。将

createTask
操作转换为异步操作,例如另一个 thunk 动作,并处理状态切片的
extraReducers
中的解析值。

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import Cookies from "universal-cookie";
import { decode } from "jsonwebtoken";

export const initialState: any = {
  tasks: [],
  status: "idle",
};

// ========== Thunks ========== \\
import { taskThunk } from "./thunks/task.thunk";
import { useGraphql } from "../../../helper/useGraphql";

export const createTask = createAsyncThunk(
  "task/createTask",
  async ({ taskName, taskTags }, ThunkAPI) => {
    const cookie = new Cookies();
    const token = cookie.get("token"); // <-- get token when action is called
    const { id }: any = decode(token);

    try {
      const graphqlSchema = `
        mutation addTask($taskInput: TaskInput!) {
          createTask(taskInput: $taskInput) {
            _id
            taskName
            tags {
              color
              name
            }
          }
        }
      `;

      const variables = {
        taskInput: {
          taskName,
          tags: taskTags,
          userId: id,
        },
      };

      const { response } = await useGraphql(graphqlSchema, variables);

      return response.data.createTask;
    } catch (error) {
      console.log("Error in createTask reducer:", error);

      return ThunkAPI.rejectWithValue(error);
    }
  },
);

const TaskSlice = createSlice({
  name: "task",
  initialState,
  extraReducers: (builder) => {
    builder
      .addCase(taskThunk.fulfilled, (state, action) => {
        try {
          const tasks = action.payload.getTasks;

          state.tasks = tasks;
          state.status = "success";
        } catch (error) {
          throw error;
        }
      })
      .addCase(createTask.fulfilled, (state, action) => {
        state.tasks.push(action.payload); // <-- add new task
      });
  },
});

export default TaskSlice.reducer;
© www.soinside.com 2019 - 2024. All rights reserved.