Home > Blockchain >  How do I get a form to submit the first time I hit enter in react?
How do I get a form to submit the first time I hit enter in react?

Time:11-23

I feel like there is an easy fix for this but I am not finding it. After I first open the page, type a number in the input and hit submit I get an empty array in the console and no number is displayed. When I hit enter again it works. How do I get the number to display the first time?

import React from 'react';
import {useState} from 'react';

const ShowDays = () =>{
const [totalMiles, setTotalMiles] = useState([])
const [miles, setMiles] = useState([])
const [total, setTotal] = useState([])

const handleChange = (e) =>{
  setMiles(e.target.value)

}

const handleSubmit = (e) =>{
  e.preventDefault();

  setTotalMiles([...totalMiles].concat(Number(miles)
  
  ))

  if (totalMiles !== []){
   let result = totalMiles.reduce((total, n) =>{
      return total  = n
    })
    setTotal(result)

  }
  

}

return (
  <div>
  <form onSubmit={handleSubmit}>
    <input type='text' placeholder='enter miles' onChange={handleChange} value={miles}/>
    <button>Submit</button>
  </form>
  <p>{`Total Milage: ${total} `}</p>
  </div>
)
    
}

export default ShowDays;

I've tried many different things but nothing seems to work

CodePudding user response:

The Array.concat method concatenates two arrays, but you're passing a number. Instead, consider setting the total miles this way:

setTotalMiles([...totalMiles, Number(miles)]);

Also, I recommend not storing total as its own state since it's completely derived from existing state. You can just calculate it in the function body:

import React from "react";
import { useState } from "react";

const ShowDays = () => {
  const [totalMiles, setTotalMiles] = useState([]);
  const [miles, setMiles] = useState([]);

  const handleChange = (e) => {
    setMiles(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    setTotalMiles([...totalMiles, Number(miles)]);
  };

  const total = totalMiles.reduce((total, n) => total   n, 0);

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          placeholder="enter miles"
          onChange={handleChange}
          value={miles}
        />
        <button>Submit</button>
      </form>
      <p>{`Total Milage: ${total} `}</p>
    </div>
  );
};

export default ShowDays;

Here is a working codesandbox link.

CodePudding user response:

I think it is important to understand why this is happening.

The setState hook is asynchronous. So by the time you trying to check the value in the if statement. The state setter hasn’t yet finished. So the value doesn’t yet exit in current state which has been queued to be available in the next life cycle.

const handleSubmit = (e) =>{
  e.preventDefault();

  setTotalMiles(prevState => ([…prevState, Number(miles)])
  
  ))

  if (totalMiles.length){
   let result = totalMiles.reduce((total, n) =>{
      return total  = n
    })
    setTotal(result)
  }
  
}

See docs. https://reactjs.org/docs/hooks-reference.html#usestate

  • Related