Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Calculadora

0

98
Vistas
How to properly use a for loop in getting the values of inputs in React.js?

The following code has a button to add inputs and another button to add all of the values in the inputs assuming they are numbers. The last line is to display the sum of everything. However, for some reason it only gets the value of the last input. It also does not reset. I thought having the setGrade(0) would do this but it just keeps adding the last number without resetting.

I would just like to know why this is the case with the following code. The id for the input fields are just the number starting from 1.

function Start(){
 const [rows, setRows] = useState([]);
 const [inputNum,setNum] = useState(1);
 const [totalGrade, setGrade] = useState(0);


 const addInput = () =>{
   setNum(inputNum+1);
   setRows(rows.concat(<Inputs key={rows.length} label={inputNum.toString()}></Inputs>));
 }

 const addGrade = () =>{
   setGrade(0);
   for(let i =0;i<rows.length;i++){
     setGrade(parseInt(document.getElementById((i+1).toString()).value,10) +totalGrade)
   }
 }

 

 return(
   <div>
     <h1>Calculate your GPA!</h1>
     {rows}
     <button class="button2"onClick={addInput}>Add Input</button>
     <button class="button2"onClick={addGrade}>Compute Grade</button>
     <h2>Grade: {totalGrade}</h2>
   </div>
 );
}
7 months ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

  1. You shouldn't be mixing native element methods like getElementById in React code.

  2. Add an onChange directly onto the input elements.

  3. Create a new state (an object) that maintains a record of each change to an input (identified by key/id) where the value is the new value of the input.

  4. Don't set state in a loop - it's bad practice.

Here's how I've approached it (I've had to simplify the example as I don't have access to the Inputs component.)

const { useEffect, useState } = React;

  function Example() {

    const [inputNum, setInputNum] = useState(0);

    // The new state which maintains all the input values
    const [inputData, setInputData] = useState({});
    const [totalGrade, setTotalGrade] = useState(0);

    // `addInput` is now only responsible
    // for updating the number of rows
    function addInput() {
      setInputNum(inputNum + 1);
    }

    // NEW FUNCTION: it handles the update of the
    // `inputData` state. It grabs the id and value from
    // the input, and then updates the state with that
    // new information
    function handleChange(e) {
      const { id, value } = e.target;

      // Take the previous state (object), and update it
      // by spreading (copying) out the previous object,
      // and adding a new property with the id as key
      // and the value as the value.
      setInputData(prev => ({ ...prev, [id]: value }));
    }

    // `sumGrade` - I renamed this - grabs the Object.values
    // of the inputData state and then creates a sum of all
    // of those values using `reduce`. It then, finally, sets
    // the `totalGrade` state.
    function sumGrade() {
      const values = Object.values(inputData);
      const result = values.reduce((acc, c) => {
        return acc + +c;
      }, 0);
      setTotalGrade(result);
    }

    // NEW FUNCTION: this builds an array of new inputs
    // which can be used in the JSX
    function buildRows() {
      const arr = [];
      for (let i = 0; i < inputNum; i++) {
        arr.push(<input onChange={handleChange} type="number" key={i} id={i} value={inputData[i]}/>);
      }
      return arr;
    }

    return (
     <div>
       <h1>Calculate your GPA!</h1>
       {buildRows()}
       <button class="button2"onClick={addInput}>Add Input</button>
       <button class="button2"onClick={sumGrade}>Compute Grade</button>
       <h2>Grade: {totalGrade}</h2>
     </div>
    );
  }

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
input { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar empleo Planes Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2023 PeakU Inc. All Rights Reserved.