0

I wrote a simple component in React which is supposed to remove the last element of an array when a button is clicked, but despite console logging the correct value, my React state is not being updated accordingly (when viewing the components with React Developer Tools) and hence the output is not changing. I'm at a loss as to why it won't update correctly.

const Test = () => {
const [input, setInput] = useState(["c", "a", "t"])

const removeLastElementFromArray = () => {
    setInput(prev => {
        console.log("Previous array was:", prev)
        let t = prev.pop();
        console.log("Array popped, array is now:", prev)
        return prev;
    })
}
return (
    <>
        <button onClick={removeLastElementFromArray}>Click</button>
        {input.map((char, index) => <span key={index}>{char}</span>)}
    </>
)

}

Jack
  • 13
  • 3

1 Answers1

0

See the state is not getting updated because arrays are mutable data types and when you pop an element, it is not going to change the address of the array in the memory. Since the array(address) has not changed, react will figure the state hasn't changed and that's why a re-render won't be triggered

Try this code

const App = () => {
  const [input, setInput] = useState(["c", "a", "t"])
  
  const removeLastElementFromArray = () => {
      setInput(prev => {
          console.log("Previous array was:", prev)
          prev.pop();
          let t= [...prev]
          console.log("Array popped, array is now:", prev)
          return t;
      })
  }
  return (
      <>
          <button onClick={removeLastElementFromArray}>Click</button>
          {input.map((char, index) => <span key={index}>{char}</span>)}
      </>
  )
}
Mridul Gupta
  • 807
  • 1
  • 6
  • 8
  • Thanks very much for your suggestion, although this now has the effect of removing one element on the first click, but then removing 2 elements on the next click (rather than one element at a time). – Jack Jul 07 '22 at 18:43
  • it only removes one element at a time, on the first click it removes 't' and then returns ['c', 'a'] as the new state, on the second click again it removes the last element which is 'a' in our case and returns ['c'] as our new state. this is how the code is functioning, if I'm right what you are trying to ask is you only wanna remove one element and then after that no matter how many times you are clicking nothing should be removed ? – Mridul Gupta Jul 07 '22 at 18:48
  • Ah, that's not the behaviour I get when I run this code. For me, after one click the state is ["c", "a"], and then after 2 clicks the state is [ ]. – Jack Jul 07 '22 at 18:50
  • I would like it to remove one element at a time (the last element) on each click, as you described – Jack Jul 07 '22 at 18:51
  • I m running the above-mentioned code and it's not happening with me, have you altered the code ? – Mridul Gupta Jul 07 '22 at 18:55
  • i have tried it with a couple of examples and its working – Mridul Gupta Jul 07 '22 at 18:57
  • Oh that's odd, I haven't altered the code but it doesn't work correctly for me unfortunately. – Jack Jul 08 '22 at 13:23
  • I have just altered your code slightly to remove prev.pop() and instead used t.pop() after t=[...prev] and now it works perfectly! Thank you. – Jack Jul 08 '22 at 13:26