Home > Software design >  Array.push() replacing value instead of adding it to the array in javascript (reactJs)
Array.push() replacing value instead of adding it to the array in javascript (reactJs)

Time:03-12

The Array doesn't grow, it either stays empty or keeps updating the same object instead of adding a new object every time.

function Resident() {
    const [newResObj, setNewResObj] = useState({});
    
    const newResArray = []; //I want all the objects to be stored inside this array

    useEffect(()=>{
      newResArray.push(newResObj);
      console.log(newResObj) //it is the right object

    }, [newResObj])

     function handleAddResidentClick() {
        const name = document.querySelector('.add_name_js').value;
        const phone = document.querySelector('.add_phone_js').value;

        props.setNewResObj({Name: name, Phone: phone});
    }

     return (
        <div className="form-group">
          <label htmlFor="formResidentName">Resident Name</label>
          <input 
            type="text" 
            className="form-control add_name_js" 
            name="ResidentName" 
            id="formResidentName" 
            placeholder="Ex. Juan Perez"/>
        </div>
        <div className="form-group">
          <label htmlFor="formPhoneNumber">Phone Number</label>
          <input 
            type="text" 
            className="form-control add_phone_js" 
            name="PhoneNumber" 
            id="formPhoneNumber" 
            placeholder="Ex. 5162222222"/>
        </div>


    <button type="button" onClick={handleAddResidentClick()}>Add<button/>
    )

This code is taken from two different react components.

CodePudding user response:

const {useState} = React;

const Resident = () => {

// declare individual elements using useState
  const [name, setName] = useState('');
  const [phone, setPhone] = useState('');

// keep info that needs to be retained across renders in useState
  const [resArr, setResArr] = useState([]);

// on Add-button click, update resArr and clear-out existing name, phone
  const handleAddResidentClick = () => setResArr(prev => ([
      ...prev,
      { name, phone}
    ]),
    (setName(''), setPhone(''))
  );

// on Delete-button click, remove just the one element from resArr
  const handleDeleteClick = idx => setResArr(prev => {
    prev.splice(idx, 1);
    return [...prev];
  });

// on each of the input elements, add 'value' & 'onChange'
  return (
    <div className="form-container">
      <div className="form-group">
        <label htmlFor="formResidentName">Resident Name</label>
        <input
          value={name}
          onChange={e => setName(e.target.value)}
          type="text" 
          className="form-control add_name_js" 
          name="ResidentName" 
          id="formResidentName" 
          placeholder="Ex. Juan Perez"
        />
      </div>
      <div className="form-group">
        <label htmlFor="formPhoneNumber">Phone Number</label>
        <input
          value={phone}
          onChange={e => setPhone(e.target.value)}
          type="text" 
          className="form-control add_phone_js" 
          name="PhoneNumber" 
          id="formPhoneNumber" 
          placeholder="Ex. 5162222222"
        />
      </div>
      <div className='button-container'>
        <button onClick={handleAddResidentClick}>
          Add Resident
        </button>
      </div>
      <div id='ResidentArray'>
        {resArr && Array.isArray(resArr) && (
          resArr.map((r, idx) => (
            <div key={idx}>
              Resident Name: {r.name} &emsp;
              Phone: {r.phone} &emsp;&emsp;
              <button onClick={() => handleDeleteClick(idx)}>
                Delete
              </button>
            </div>
          ))
        )}
      </div>
    </div>
  );

};

ReactDOM.render(
  <div>
    <h4>Demo</h4>
    <Resident />
  </div>,
  document.getElementById('react')
);
.form-container { border: 2px solid grey; }

.form-group {
  padding: 10px 35px;
  background-color: #CCCCFF;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  border-bottom: 2px dashed #AAAA66
}

.button-container {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 0;
}
<div id='react'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

Explanation

  • Please check comments within the code-snippet
  • The basic idea is to avoid directly accessing the DOM
  • Instead, use value and onChange for the two input-s.
  • Added the ability to display the array as well as delete a particular element from the array.
  • Related