import { useState } from "react";
const Usestatetry3 = () => {
const[name,setName] = useState({fname:"",lname:""} );
const gettingValue = (e) =>{
setName(e.target.value)
console.log(e.target.value)
}
return(
<>
<div className="bg-blue-200 p-5 text-3xl flex-cols space-y-5 justify-center items-center">
<div>
<label className='text-red-500'>First Name
<input className='ml-6' type='text' placeholder='insert your First Name...' value={name.fname } onChange={gettingValue} />
</label>
</div>
<div>
<label className='mr-5 text-red-900'>Last Name
<input className='ml-6' type='text' placeholder='insert your Last Name...' value={name.lname } onChange={gettingValue} />
</label>
</div>
<p>input value is:<span className='text-brown-200 ml-1'>{name.fname}{name.lname}</span></p>
</div>
</>
)
}
After run the above code there is warning for error in console : Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
The error you are encountering is due to the way you are updating the name
state. You need to handle the state update correctly for the individual fields (fname
and lname
). Here's how you can do it:
- Use the
name
state object properly. - Ensure that you are updating the correct property of the state object.
Here's the corrected code:
import { useState } from "react"; const Usestatetry3 = () => { const [name, setName] = useState({ fname: "", lname: "" }); const gettingValue = (e) => { const { name, value } = e.target; setName(prevState => ({ ...prevState, [name]: value })); console.log({ [name]: value }); }; return ( <> <div className="bg-blue-200 p-5 text-3xl flex-cols space-y-5 justify-center items-center"> <div> <label className='text-red-500'>First Name <input className='ml-6' type='text' name='fname' placeholder='insert your First Name...' value={name.fname} onChange={gettingValue} /> </label> </div> <div> <label className='mr-5 text-red-900'>Last Name <input className='ml-6' type='text' name='lname' placeholder='insert your Last Name...' value={name.lname} onChange={gettingValue} /> </label> </div> <p>input value is:<span className='text-brown-200 ml-1'>{name.fname} {name.lname}</span></p> </div> </> ); }; export default Usestatetry3;
- Added
name
attribute to the input fields to distinguish betweenfname
andlname
. - Updated the
gettingValue
function to handle the changes correctly usingname
andvalue
frome.target
. - Spread the previous state to retain the other property values when updating.
This should resolve the warning and handle the state updates correctly.
Now i will explain the code above :
about this section :
const [name, setName] = useState({ fname: "", lname: "" });
const gettingValue = (e) => {
const { name, value } = e.target;
setName(prevState => ({
...prevState,
[name]: value
}));
console.log({ [name]: value });
In the gettingValue
function, you need to handle changes for both the first name and last name inputs. The key is to know which input triggered the change event. By using e.target.name
, you can identify the input (either fname
or lname
) and update the corresponding state property.
Here’s a breakdown of the key parts:
Destructuring
e.target
:
This line extracts the name
and value
properties from the event target (e.target
). The name
corresponds to the name
attribute of the input field, and the value
is the current value of the input field.
Using setName
with a callback function:
setName(prevState => ({ ...prevState, [name]: value }));
prevState
is the previous state value....prevState
spreads the previous state values into the new state object.[name]: value
dynamically updates the property (either fname
or lname
) with the new value.This way, you can update the correct property (fname
or lname
) based on which input field was changed.
If you simply used e.target.value
without considering the name
attribute, you wouldn't know which property to update. Here’s how it works in practice:
Explanation with an Example:
When you type in the "First Name" input:
e.target.name
is"fname"
e.target.value
is the new value entered- The state update looks like:
{ fname: newValue, lname: previousLnameValue }
When you type in the "Last Name" input:
e.target.name
is"lname"
e.target.value
is the new value entered- The state update looks like:
{ fname: previousFnameValue, lname: newValue }
Here's the relevant section of code again with added comments for clarity:
const [name, setName] = useState({ fname: "", lname: "" }); const gettingValue = (e) => { // Destructure name and value from e.target const { name, value } = e.target; // Update the state dynamically based on the input name setName(prevState => ({ ...prevState, // Keep all other state properties [name]: value // Update the specific property based on input name })); // Log the updated value for debugging console.log({ [name]: value }); };
import { useState } from "react";