首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Immer.js向嵌套状态数组/对象添加新项时,React视图不会更新

使用Immer.js向嵌套状态数组/对象添加新项时,React视图不会更新
EN

Stack Overflow用户
提问于 2022-11-13 17:27:59
回答 1查看 28关注 0票数 0

问题:未更新react视图

我有一种状态,其组成如下:

代码语言:javascript
复制
[
  {
    date: "12/10/2022",
    data: [
      { id: "1", title_tax: "tax number one" },
      { id: "2", title_tax: "tax number two" },
    ],
  },
  {
    date: "13/10/2022",
    data: [{ id: "3", title_tax: "tax number three" }],
  },
];

数据对象是存储更多对象的数组,这通常是我们添加更多项的地方。向上下文添加项的过程很好,并且正确添加了这些项,但是用户视图不会更新这些新项。

在我的组件中,我有一个数组(cardsHistory),它基本上接收我显示的状态,然后创建可视化。我没有什么例外,我只是想找个办法来解决这个问题。

代码语言:javascript
复制
interface IProps {
  cardsHistory: IPropsHistoryCard[];
  loadMoreHistories: () => void;
  isData: boolean;
}

function ScrollHistory({ cardsHistory, loadMoreHistories, isData }: IProps) {
  const histories: IPropsHistoryCard[] = cardsHistory;
  console.log(histories);
  return (
    <InfiniteScroll pageStart={1} loadMore={loadMoreHistories} hasMore={isData}>
      {histories && histories?.length > 0 ? (
        histories.map((x: IPropsHistoryCard) => (
          <HistoryCard key={x.date} date={x.date} data={x.data} />
        ))
      ) : (
        <Typography>No history to display</Typography>
      )}
    </InfiniteScroll>
  );
}

export default ScrollHistory;

以防万一,当我收到一个新的项目时,我使用的是immer的产品。

代码语言:javascript
复制
case DashboardActionTypes.addHistory:
      return produce(state, (draft) => {
        const newElement: IProcess = payload;
        const dayIncluded = new Date(
          newElement.startDateTime,
        ).toLocaleDateString();

        const processElement: IProcess[] = [];
        processElement.push(newElement);

        if (draft.history.length === 0) {
          const historyElement: IPropsHistoryCard = {
            date: dayIncluded,
            data: processElement,
          };
          draft.history.push(historyElement);
        } else {
          const index = draft.history
            .map((object) => object.date)
            .indexOf(dayIncluded);
          if (index < 0) {
            const historyElement: IPropsHistoryCard = {
              date: dayIncluded,
              data: processElement,
            };
            draft.history.push(historyElement);
          } else {
            const isInArray = draft.history[index].data.find(
              (element) => element.id === newElement.id,
            );
            if (isInArray === undefined)
              draft.history[index].data.push(newElement);
          }
        }
      });
EN

回答 1

Stack Overflow用户

发布于 2022-11-13 17:38:29

React并不能对道具进行深入的检查,而只是肤浅的检查。因此,如果最外层的对象不改变,React将从重新呈现组件的过程中退出。

react中的任何状态更新都必须将最外层的对象更改为有效,这样就不能与数组重叠,必须用一个新的对象来替换它。

代码语言:javascript
复制
newArray = [...oldArray, newItem]

我避免奇怪的副作用在反应所有的对象应该是不可变的,因此不要改变对象(除非他们明确地不打算影响一个组件呈现)。

有一些帮手可以用来处理它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74423195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档