0

I have the following React component. I am relatively new to react, so don't have all the concepts of using hooks firmly in my grasp.

I've seen a few other questions pointing to the asynchronous nature of the setState function but that does not seem to be the issue here.

Expectation from the code: I expect that as the user inputs values in the fName and lName inputs, the h1 gets automatically updated and rendered

What Actually Happens: As I enter values in the inputs, the typed value does not show up in the input fields on the UI. The heading (h1) also does not update.

Additional Note: The code works as expected if I use "if" statements to check and conditionally update the corresponding property of the Object instead of using prevState[name] = value; in setHeadingText.

import React, {useState} from "react";

function App() {

  const [headingText, setHeadingText] = useState({
    fName: "",
    lName: ""
  });


  function handleChange(e){

    const {name, value} = e.target;
    
    setHeadingText(prevState => {
      prevState[name] = value;
      return prevState;
    })
  }

  return (
    <div className="container">
      <h1>Hello {headingText.fName + " " + headingText.lName}</h1>
      <input type="text" name="fName" placeholder="First Name" value={headingText.fName} onChange={handleChange}/>
      <input type="text" name="lName" placeholder="Last Name" value={headingText.lName} onChange={handleChange}/>
      <button>
        Submit
      </button>
    </div>
  );
}

export default App;
The Guru
  • 55
  • 6
  • That's not how the callback works, and don't mutate state. [When to use React setState callback](https://stackoverflow.com/questions/42038590/when-to-use-react-setstate-callback) – Andy Ray Aug 09 '21 at 17:05

2 Answers2

1

You're not updating the identity of the object, you're updating the object internally. React can't see that change.

Separate fName and lName into separate state atoms or update the entire state object into a new object instead of mutating it internally:

setHeadingText(prevState => ({...prevState, [name]: value})) 
AKX
  • 152,115
  • 15
  • 115
  • 172
0

The prevstate is the first param of the array headingText rendered useState to change the state you have just to excute passe the object directcly by the same type parameter Object

You have to replace

setHeadingText(prevState => {
      prevState[name] = value;
      return prevState;
    })

with

setHeadingText({
      ...headingText,
      [name]:value
    })