2

I was changing a state between renders and logging that value on every time the state changes via useEffect. I noticed my console is showing this error bellow: image of console showing the error.

[Edit] This text of error

Warning: The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant.

Previous: [[object Object], entity1]
Incoming: []

I'm not understanding why is it that I'm getting this error. It would be very helpful if someone could explain why is my console showing this error.

Here's the code if it helps:

import React, { useEffect, useState } from "react";
import Item from "./Item";
import { Item as ItemType } from "../types";

const Content: React.FC = () => {
  const [items, setItems] = useState<Array<ItemType>>([
    { id: 1, checked: false, item: "Banana" },
    { id: 2, checked: false, item: "Potato" },
    { id: 3, checked: false, item: "Charger" },
  ]);

  const onItemChecked = (id: number) => {
    const _items = items.map((item) =>
      item.id === id ? { ...item, checked: !item.checked } : item
    );
    setItems(_items);
  };

  const onItemDeleted = (id: number) => {
    const _items = items.filter((item) => item.id !== id);
    setItems(_items);
  };

  useEffect(() => {
    console.log(items);
  }, items);

  return (
    <main>
      <ul>
        {items.map((item) => (
          <Item
            item={item}
            key={item.id}
            onItemChecked={onItemChecked}
            onItemDeleted={onItemDeleted}
          />
        ))}
      </ul>
    </main>
  );
};

export default Content;

5
  • 1
    Because it's the dependency array? The name kind of tells you what it's for: any variable in the array whose value changes will cause the side effect code to rerun. Leave the array empty and now you've guaranteed the side effect code will only ever run once, because you told React that there "are dependencies", and then you gave it a list that will never change. The one rule is that the array always has the same variables in the same places. And on a "posting to SO" node: do not post pictures of text: edit your post and copy-paste the actual text in. Commented Aug 15, 2023 at 5:08
  • @Mike'Pomax'Kamermans Sorry, my question's title was not on point - but I edited that. I'm asking why is it that - the variable that is on the dependency array of useEffect, cannot change it's size as the error message is showing. Commented Aug 15, 2023 at 5:18
  • Except you're not passing "a dependency array containing a variable", you're just passing "the variable" on its own. Commented Aug 15, 2023 at 14:41
  • @Mike'Pomax'Kamermans, what if I really want to execute the function related to the deps array considering the items of the array, not the array itself? Just to clarify: what if I want that function to run only if the content of the array changes? Say I do something like setItems([...items). In this case, the array "items" will be different, and the function associate to a deps array [items] will run, even if nothing inside that array really had changed. Commented Mar 5 at 21:10
  • Then... you... write proper code and you make sure to trigger whatever code you need triggered at the same time you call setItems? Without a real use-case, this is a very weird situation to ask about: if the items didn't change then nothing changed, and so there are no side effects that need triggering, because again: nothing changed. Commented Mar 5 at 23:18

2 Answers 2

1

Should be

useEffect(() => {
    console.log(items);
  }, [items]);
Sign up to request clarification or add additional context in comments.

Comments

0

Could you update your code like below? Your way to use useState is not correct.

import React, { useEffect, useState } from "react";
import Item from "./Item";
import { Item as ItemType } from "../types";

const Content: React.FC = () => {
  const [items, setItems] = useState<Array<ItemType>>([
    { id: 1, checked: false, item: "Banana" },
    { id: 2, checked: false, item: "Potato" },
    { id: 3, checked: false, item: "Charger" },
  ]);
  const onItemChecked = (id: number) => {
    setItems(_items => _items.map((item) =>
      item.id === id ? { ...item, checked: !item.checked } : item
    ));
  };
  const onItemDeleted = (id: number) => {
    setItems(_items => _items.filter((item) => item.id !== id));
  };
  useEffect(() => {
    console.log(items);
  }, [items]);
  return (
    <main>
      <ul>
      {items.map((item) => (
        <Item
          item={item}
          key={item.id}
          onItemChecked={onItemChecked}
          onItemDeleted={onItemDeleted}
        />
      ))}
    </ul>
  </main>
  );
};
export default Content;

Comments

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.