0

Problem: react view is not updated

I have a state that has the following composition:

[
  {
    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" }],
  },
];

the data object is an array that stores more objects, this is usually where we add more items. The process of adding items to the context is fine and they are added correctly, but the user view does not update these new items.

In my component I have an array (cardsHistory) that basically receives the state I showed and then creates the visualization. I don't have any exceptions or anything, I'm just looking for a way to fix this.

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;

just in case when i recieve a new item I'm using immer produce from immer

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);
          }
        }
      });
5
  • 1
    You can't modify the state directly in react. You have two create a new object every time you want to change t Commented Nov 13, 2022 at 17:35
  • @KonradLinkowski I'm using immer for create the new state when i recive a new item Commented Nov 13, 2022 at 17:36
  • 1
    Found related - stackoverflow.com/questions/71185474/… Commented Nov 13, 2022 at 17:41
  • @CoolLife you should probably show how the items are getting added .... Commented Nov 13, 2022 at 17:42
  • @KcH I just edited my question Commented Nov 13, 2022 at 17:46

1 Answer 1

2

React does not perform a deep-check on the props, but just a shallow one. So if the outher most object does not change React will bail out from re-rendering your component.

Any state update in react must change the outher most object to be effective so you cannot apped to the array, you have to replace it with a new one.

newArray = [...oldArray, newItem]

I avoid strange side effets in React all object shall be immutable, therefore do not mutate objects (unless they are explicitly not meant to affect a component rendering).

There are some helpers available to deal with it.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks I understand the concept, I checked it but I'm using immer that produces a new state every time I change the current one, in theory it should be almost the same.
I see, I edited your question to disambiguate. Silly question, have you checked there are no duplicate keys, they may lead to strange rendering behaviours? Furthermore you are discussing about the data field so we need code for the HistoryCard component.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.