Phelizer
Phelizer

Reputation: 319

React weird implicit mutation of state

I have TaskManager component in which I have state

const [sections, setSections] = useState({
sectionArr: [/*some stuff*/],
taskArr: [/*some stuff*/],
})

and a bunch of conlole.logs

  console.log("Sections is", sections);
  console.log("Type: ", typeof sections);

Also I have AddSectionButton which is basically a button that adds new sections. It's onClick callback function is

  const handleClick = () => {
    const newObject = {
      name: "added section",
      id:
        // random id
        Math.floor(Math.random() * (Number.MAX_VALUE - 0)) + 0,
      position: 0,
    };
    const sectionsCopy = sections;
    const updatedState = sectionsCopy.sectionArr.push(newObject);

    setSections(updatedState);
  };

When I run my application at first everything is ok, my console.logs output is correct

Sections is {sectionArr: Array(3), taskArr: Array(3)}
Type:  object
(3) [{…}, {…}, {…}]
ƒ map() { [native code] }

But then when I click my AddSectionButton - output gets really weird

Sections is 4
Type:  number

I no way changed my whole state with 4. Any ideas about why my state changes?

Upvotes: 1

Views: 139

Answers (1)

ZimZimma
ZimZimma

Reputation: 228

rray#push method works in situ, you don't have to assign it to a new variable. It won't return a new array, but will modify the original one and will return it's length. That's why you are getting a number as the result.

I would do something like this instead of using push

updateState = { sectionArr: [...sectionsCopy.sectionArr, newObject], taskArr: [...sectionsCopy.taskArr] }

Or even maybe using the sectionsCopy variable to pass to the setSections because using push would mutate that variable and return the number.

Upvotes: 2

Related Questions