Home > Back-end >  Element obtaining value from input only updating after the second time I press enter. Why is this ha
Element obtaining value from input only updating after the second time I press enter. Why is this ha

Time:02-21

I am just trying to figure out how to do my to-do list and currently am just experimenting with adding elements containing text given a text input element.

The issue is presented in this clip: https://imgur.com/a/DDTyv1I

import { useState } from "react"

function App() {
  const [inputVal, setInputVal] = useState('')
  const [tasks, setTasks] = useState([])

  console.log(inputVal);
  return <>
    <Input valor = {setInputVal} inputVal={inputVal} tasks={tasks} setTasks={setTasks}/>
    {
      tasks.map(e=>(
        <Display text={e.text}/>
      ))
    }
  </>
}

const Input = ({valor, inputVal, tasks, setTasks}) =>{
  const keyPressed = (val) =>{
    if(val.key === 'Enter'){
      valor(val.target.value)

      setTasks([
        ...tasks, {text: inputVal, key: Math.random()*2000}
      ])
    }
  }

  return <>
    <input type="text" onKeyUp={keyPressed}/>
  </>
}

const Display = ({text}) => {
  return <>
    <h1>{text}</h1>
  </>
}

export default App;

CodePudding user response:

I believe this is happening because you are not using onChange on your input so your state is going stale and you are always one value behind.

I have tidied up the code and added some missing pieces (like the value attribute in the input element).Then I split the function that takes care of the submission to 2 functions - one function that is handling changing the input value and one that submits the value as a new entry to your tasks list

import { useState } from "react"

const Input = ({ input, handleChange, tasks, setTasks }) => {

    const onSubmit = (e) => {
      if (e.key === 'Enter') {
        setTasks([
          ...tasks, 
          { text: input, key: Math.random()*2000 }
        ])
        setInput('');
      }
    }

    const handleChange = (e) => {
      setInput(e.target.value)
    }
  
    return <input type="text" onKeyUp={onSubmit} onChange={handleChange} value={input}/>
}
  
const Display = ({ text }) => <h1>{text}</h1>

const App = () => {
  const [input, setInput] = useState('')
  const [tasks, setTasks] = useState([])

  return <>
    <Input input={input} setInput={setInput} tasks={tasks} setTasks={setTasks}/>
    {tasks.map((task) => (
        <Display text={task.text}/>
      ))
    }
  </>
}

CodePudding user response:

When keyPressed is called, your code calls setInputVal (valor) and setTasks. The setTask is being called before setInputVal actually has time to update the state, so it sets the ”old” value. This is because state setting is asynchronous and the code does not wait for the inputVal to be set before setting the task.

  • Related