0

I am tring to push new value to arrays but the arrays is not updating with new values. It only contains one value after push. The arr value after button click only showing one value, but I want it to have multiple values. What are multiple ways to put values into arr variable or copy value to another variable?

function App() {
  const [value, setValue] = useState(null);
  let arr = [];

  function addToArr() {
     console.log(value);
     arr.push(value);

     console.log(arr);   // it is only showing one value
  }

  return (
    <div>react app
      <div>
          <textarea
            value={value}
            onChange={(e) => setValue(e.target.value)}
          >
          </textarea>

        <button onClick={addToArr}>Add</button>
      </div>
    </div>
 );
}

export default App;
5
  • 1
    You can use a ref for this, or state if you need the UI to update when arr is updated. Commented May 3, 2022 at 10:32
  • @NickParsons, apologies if this is a rather dumb question: how could one use ref in this context? I understand using a state variable to hold arr will do the trick; but, couldn't quite figure-out (for myself) how ref would help solve. Commented May 3, 2022 at 10:38
  • 3
    @jsN00b It would be something along the lines of const arr = useRef([]), and then instead of OP doinng arr.push(value) they could use arr.current.push(value) :) Commented May 3, 2022 at 10:42
  • @NickParsons Thanks, It works. If I want to assign it a new variable like this let copyValue = value, then what will be correct approach. Commented May 3, 2022 at 11:02
  • 1
    @i_am_learning You can set the value of the ref by updating the .current value: arr.current = value if that is what you're after? Commented May 3, 2022 at 11:10

3 Answers 3

2

Your problem is you put let arr = []; in the component App which will be re-rendered whenever the state changes, your arr will be reset as well.

One possible fix could be moving your arr declaration out of the component App

let arr = []; //move it to the global scope
function App() {
  const [value, setValue] = useState(null);

  function addToArr() {
     console.log(value);
     arr.push(value);

     console.log(arr); 
  }

  return (
    <div>react app
      <div>
          <textarea
            value={value}
            onChange={(e) => setValue(e.target.value)}
          >
          </textarea>

        <button onClick={addToArr}>Add</button>
      </div>
    </div>
 );
}

export default App;

If you want to keep arr internally, you can use useRef which only refers to the same object during re-renderings

import React, { useRef, useState } from 'react'
function App() {
  const [value, setValue] = useState(null);
  const arrRef = useRef([]);

  function addToArr() {
     console.log(value);
     arrRef.current.push(value);

     console.log(arrRef.current);  
  }

  return (
    <div>react app
      <div>
          <textarea
            value={value}
            onChange={(e) => setValue(e.target.value)}
          >
          </textarea>

        <button onClick={addToArr}>Add</button>
      </div>
    </div>
 );
}

export default App;
Sign up to request clarification or add additional context in comments.

Comments

1

For this you have 2 ways:

  1. Lifting arr variable before component
let arr = [];
function App() {
  const [value, setValue] = useState(null);
  ...
}
export default App;
  1. Using a new state
function App() {  
  ...
  const [newArrValue, setnewArrValue] = useState([]);

  const addToArr = () => {
    ...    
    newArrValue.push(value);
    setnewArrValue(newArrValue);
    console.log(newArrValue); 
  };
  ...
}
export default App;

Comments

0

Using the useState, you can try this:

var [array, setArray] = useState(["a", "b"]);
const fun = () => {
    setArray((oldArray) => [...oldArray, "c"])
}
fun()

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.