Redux Toolkit:状态显示为Proxy /在reducer中未定义

解决了,谢谢!-对于感兴趣的任何人,我都试图在化简器中访问state.tasks.data,但是由于范围的原因,我可以通过state.data访问它,因为我已经在任务片中了。


编辑:我的突变状态错误问题现已解决,这是由于直接对状态进行排序而没有从中创建新数组。concat()之前已经解决了sort()

我的新问题是stateremoveTask reducer内部不再可用。现在返回未定义。如果我console.log(state)那么它将返回一个Proxy

[[Handler]]: null,
[[Target]]: null,
[[IsRevoked]]:true

编辑2:我发现代理服务器是由于immer在幕后进行的,它会对突变做一些事情,从而以state不突变的方式使用它我还没有解决state.tasks.data返回问题undefined


我正在使用react-redux和redux-toolkit。我只是在学习Redux,所以我的头被炸了,没有任何线索。

我已经在他们网站上的redux-toolkit基本教程中关注了一些信息,该信息说您可以在化简器中对状态进行突变,因为工具箱在后台进行了某些操作以阻止其实际对状态进行突变:

https://redux-toolkit.js.org/tutorials/basic-tutorial

无论如何,它们提供的反例都处于突变状态。增量减少器返回state += 1-正常工作

现在,我有了自己的东西,将已initial state放置的对象数组设置为集合。请参见下文:

tasksSlice.js

import { createSlice } from "@reduxjs/toolkit";
import data from "data/tasks_data.json";

export const tasksSlice = createSlice({
  name: "tasks",
  initialState: {
    data: data,
  },
  reducers: {
    removeTask: (state, action) => {
      const { id } = action.payload;
      const { data } = state.tasks;
      data = data.filter((item) => id !== item.id);
    },
  },
});

export const { removeTask } = tasksSlice.actions;

export const selectTasks = (state) => state.tasks.data;

export default tasksSlice.reducer;

现在,我的tasks组件中列出了任务使用taskItem组件列出了每个任务taskItem组件内部,我有一个删除按钮,我已将onClick事件设置为使用removeTaskreducer。

<button
  className={`${styles.task_button} ${styles.delete}`}
  onClick={() => dispatch(removeTask(id))}
>
  <MdDeleteForever />
</button>

这会将的“ customer_id”字段从中传递data到任务列表中initial state

我希望能够删除任务,因此我试图通过过滤state.tasks.data并返回id匹配对象的所有内容(如工具包所说的那样)对其进行变异

不幸的是,我不断收到错误消息:

Error: Invariant failed: A state mutation was detected between dispatches, in the path 'tasks.data.0'. This may cause incorrect behavior.


tasks.js -Tasks容器组件(相当混乱):

import React, { useState, useEffect } from "react";
import SectionHeading from "components/SectionHeading/SectionHeading";
import { useSelector } from "react-redux";
import { selectTasks } from "redux/tasks/tasksSlice";
import TaskSelect from "./TaskSelect";
import TaskTabs from "./TaskTabs";
import TaskItem from "./TaskItem";
import styles from "./Tasks.module.scss";
// import tasks_data from "data/tasks_data.json";

const Tasks = () => {
  const tasksData = useSelector(selectTasks);
  console.log(tasksData);
  const [taskTab, setTaskTab] = useState({ activeTask: "All" });
  const [size, setSize] = useState({ width: 65, left: 0 });
  // const [tasksData, setTasksData] = useState(tasks_data);

  const taskTypes = [
    "All",
    "Quotes",
    "Domains",
    "SSL Setup",
    "SEO Setup",
    "Other",
  ];

  useEffect(() => {
    const activeBar = document.querySelector(".active_bar");
    const active = document.querySelector(".active_btn");
    if (size) {
      activeBar.style.width = `${active.offsetWidth}px`;
      activeBar.style.transform = `translate(${active.offsetLeft}px, ${active.offsetTop}px)`;
    }
  });

  const setActive = (e, type) => {
    setTaskTab({ activeTask: type });
    setSize(false);
    const activeBar = document.querySelector(".active_bar");
    activeBar.style.width = `${e.target.offsetWidth}px`;
    activeBar.style.transform = `translate(${e.target.offsetLeft}px, ${e.target.offsetTop}px)`;
  };

  const changeActive = (e) => {
    setTaskTab({ activeTask: e.target.value });
  };

  const getDaysDue = (days) => {
    const { days_due, overdue } = days;
    if (overdue === true) {
      if (days_due === -1) {
        return `${Math.abs(days_due)} day overdue`;
      } else {
        return `${Math.abs(days_due)} days overdue`;
      }
    } else if (days_due === 0) {
      return "Today";
    } else if (days_due === 1) {
      return `${days_due} day`;
    } else if (days_due > 1) {
      return `${days_due} days`;
    } else {
      return "Error getting days due";
    }
  };
  return (
    <article className="tasks">
      <TaskTabs
        taskTypes={taskTypes}
        click={setActive}
        activeTask={taskTab.activeTask}
        data={tasksData}
      />
      <TaskSelect taskTypes={taskTypes} change={changeActive} />
      <SectionHeading>Tasks: {taskTab.activeTask}</SectionHeading>
      <section className={styles.tasks_list}>
        {tasksData
          .sort((a, b) => a.days.days_due - b.days.days_due)
          .filter((task) =>
            taskTab.activeTask === "All"
              ? true
              : task.type === taskTab.activeTask
          )
          .map(
            ({
              customer_id,
              account_name,
              days,
              days: { days_due, overdue },
              type,
            }) => {
              return (
                <TaskItem
                  key={customer_id}
                  id={customer_id}
                  name={account_name}
                  days={getDaysDue(days)}
                  overdue={overdue}
                  daysDue={days_due}
                  type={type}
                />
              );
            }
          )}
      </section>
    </article>
  );
};

export default Tasks;

TaskItem.js

import React from "react";
import { useDispatch } from "react-redux";
import { removeTask } from "redux/tasks/tasksSlice";
import { Link } from "react-router-dom";
import { MdModeEdit, MdDeleteForever } from "react-icons/md";
import styles from "./TaskItem.module.scss";

const TaskItem = ({ id, name, days, daysDue, overdue, type }) => {
  const dispatch = useDispatch();
  return (
    <article
      className={`
    ${styles.task} 
    ${daysDue === 0 ? `${styles.today}` : ""} 
    ${overdue === true ? `${styles.overdue}` : ""}
    `}
    >
      <Link to="/" className={styles.task_name}>
        {name}
      </Link>

      <span
        className={`${styles.task_days} ${
          daysDue === 0 ? `${styles.task_days__today}` : ""
        } ${overdue ? `${styles.task_days__overdue}` : ""}`}
      >
        <strong>{type}</strong>: {days}
      </span>

      <div className={styles.task_buttons}>
        <button className={`${styles.task_button} ${styles.edit}`}>
          <MdModeEdit />
        </button>

        <button
          className={`${styles.task_button} ${styles.delete}`}
          onClick={() => dispatch(removeTask(id))}
        >
          <MdDeleteForever />
        </button>
      </div>
    </article>
  );
};
export default TaskItem;

tasks_data.json

[
  {
    "account_name": "Misty's Gym",
    "customer_id": 1,
    "days": {
      "days_due": 1,
      "overdue": false
    },
    "type": "Quotes"
  },
  {
    "account_name": "Brock's Diner",
    "customer_id": 2,
    "days": {
      "days_due": 0,
      "overdue": false
    },
    "type": "Quotes"
  },
  {
    "account_name": "Samurai Champloo's Fish Bar",
    "customer_id": 3,
    "days": {
      "days_due": 5,
      "overdue": false
    },
    "type": "SSL Setup"
  },
  {
    "account_name": "Tiny Rebel",
    "customer_id": 4,
    "days": {
      "days_due": -7,
      "overdue": true
    },
    "type": "Domains"
  },
  {
    "account_name": "Matalan",
    "customer_id": 5,
    "days": {
      "days_due": 13,
      "overdue": false
    },
    "type": "Other"
  },
  {
    "account_name": "Lowes Soft Drinks",
    "customer_id": 6,
    "days": {
      "days_due": 1,
      "overdue": false
    },
    "type": "SEO Setup"
  },
  {
    "account_name": "Snack 'n' Go",
    "customer_id": 7,
    "days": {
      "days_due": -2,
      "overdue": true
    },
    "type": "Quotes"
  },
  {
    "account_name": "Jeronemo",
    "customer_id": 8,
    "days": {
      "days_due": 5,
      "overdue": false
    },
    "type": "Quotes"
  },
  {
    "account_name": "Tom's Mouse Traps",
    "customer_id": 9,
    "days": {
      "days_due": 0,
      "overdue": false
    },
    "type": "Domains"
  },
  {
    "account_name": "Contiente",
    "customer_id": 10,
    "days": {
      "days_due": 2,
      "overdue": false
    },
    "type": "Domains"
  },
  {
    "account_name": "Um Bongo",
    "customer_id": 11,
    "days": {
      "days_due": -1,
      "overdue": true
    },
    "type": "SEO Setup"
  }
]


我到底在做什么错?我还能如何设置状态?

干杯。

y

tasksData.sort(在您的Tasks组件中)修改tasksData存储中的原始数组,同样sort如此。预先制作一个新数组,例如通过tasksData.concat().sort(...

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Redux-Toolkit createAsyncThunk Dispatch显示为未定义

来自分类Dev

在mapStateToProps中未定义Redux状态

来自分类Dev

Redux状态变量显示为未定义

来自分类Dev

Redux 状态未定义

来自分类Dev

Redux Reducer没有显示我的控制台日志并返回未定义

来自分类Dev

尽管 Redux devtools 正确显示商店,但 Redux 状态返回为未定义

来自分类Dev

Redux Reducer返回了未定义的处理

来自分类Dev

更新状态后,Redux状态返回未定义

来自分类Dev

Redux状态变量在useEffect返回函数中未定义

来自分类Dev

如何在Redux Toolkit reducer中替换整个状态?

来自分类Dev

更新后Redux状态返回未定义

来自分类Dev

为什么状态未定义?[Hooks / Redux]

来自分类Dev

简单的React Redux状态返回未定义

来自分类Dev

Redux状态变量未定义

来自分类Dev

Redux初始状态导致未定义的错误

来自分类Dev

Redux 初始状态值变为未定义

来自分类Dev

为什么Redux存储显示我的状态,但是react组件说它的状态未定义?

来自分类Dev

Redux-将reducer传递给动作似乎具有未定义的ID

来自分类Dev

Redux Toolkit问题,由于未定义而获得“无法分解”属性

来自分类常见问题

在Redux Reducer中读取商店的初始状态

来自分类Dev

在Redux Reducer中更新状态的正确方法

来自分类Dev

Redux Reducer无法更新存储中的状态

来自分类Dev

在 redux reducer 中更新状态的问题

来自分类Dev

无法在 redux 中更新 reducer 状态

来自分类Dev

Javascript / Redux中未定义的对象属性

来自分类Dev

无法读取Redux中未定义的属性“类型”

来自分类Dev

Javascript / Redux中未定义的对象属性

来自分类Dev

拉API时在Redux中未定义数据

来自分类Dev

为什么我的Redux减速器认为我的状态未定义?

Related 相关文章

热门标签

归档