If I want to make a functional component that will contain a form ,to login for example, and I want to contain the state in App component and Login will be its child, can I mutate the state in App using the form in Login child?
6 Answers
import React, {useState} from 'react';
function Submit() {
const [inputField , setInputField] = useState({
first_name: '',
last_name: '',
gmail: ''
})
const inputsHandler = (e) =>{
setInputField( {[e.target.name]: e.target.value} )
}
const submitButton = () =>{
alert(inputField.first_name)
}
return (
<div>
<input
type="text"
name="first_name"
onChange={inputsHandler}
placeholder="First Name"
value={inputField.first_name}/>
<br/>
<input
type="text"
name="last_name"
onChange={inputsHandler}
placeholder="First Name"
value={inputField.last_name}/>
<br/>
<input
type="gmail"
name="gmail"
onChange={inputsHandler}
placeholder="Gmail"
value={inputField.gmail}/>
<br/>
<button onClick={submitButton}>Submit Now</button>
</div>
)
}
export default Submit

- 43
- 4

- 119
- 1
- 3
-
2This was great, except it causes a warning `Warning: A component is changing a controlled input of type text to be uncontrolled`. Fix for me for this here: https://stackoverflow.com/questions/61378837/react-input-warning-a-component-is-changing-a-controlled-input-of-type-text-to – tehlivi Oct 14 '21 at 15:36
Yes. Pass two props an object data
and a method onChange
to Login
from App
.
data
will set the values for the form in Login
.
Fire onChange
with updated form values if there is any change in Login
form.
Handle it in App
and update its state which will then flow down to Login
as data
.

- 5,132
- 1
- 11
- 21
Use something like
const payloadHandler = (e) => {
setPayload({ ...inputField, [e.target.name]: e.target.value });
};

- 100,966
- 191
- 140
- 197

- 43
- 4
-
4this is just a thrown snippet code without providing any further insights to the original question. – buzatto Feb 28 '21 at 02:51
Yes, this is possible. You just need to pass a prop to your child component. Here is an example of how to do it:
// in parent component
handleChange(updatedData) {
this.setstate({
data: updatedData
})
}
// in render method
<Login handleChange={this.handleChange}/>
// in child component
// calling the handleChange function
this.props.handleChange(newData)

- 2,478
- 2
- 22
- 45
The solution is given by the Mehedi Setu
will give the Warning: A component is changing a controlled input of type text to be uncontrolled.
I am updating the code
that will remove
this Warning
.
import React, {useState} from 'react';
function Submit() {
const [inputField , setInputField] = useState({
first_name: '',
last_name: '',
gmail: ''
})
const inputsHandler = (e) =>{
const { name, value } = e.target;
setInputField((prevState) => ({
...prevState,
[name]: value,
}));
}
const submitButton = () =>{
alert(inputField.first_name)
}
return (
<div>
<input
type="text"
name="first_name"
onChange={inputsHandler}
placeholder="First Name"
value={inputField.first_name}/>
<br/>
<input
type="text"
name="last_name"
onChange={inputsHandler}
placeholder="First Name"
value={inputField.last_name}/>
<br/>
<input
type="gmail"
name="gmail"
onChange={inputsHandler}
placeholder="Gmail"
value={inputField.gmail}/>
<br/>
<button onClick={submitButton}>Submit Now</button>
</div>
)
}
export default Submit

- 359
- 2
- 10
The set state process in React is an asynchronous process. Therefore even if the function is called, values has not updated the previous state just yet. To fix, this you can use the functional version of setState which returns the previous state as it's first argument.
Use this code below in order to get all the object values from the state
const inputsHandler = (e) => {
setInputField((inputField) => ({
...inputField,
[e.target.name]: e.target.value,
}));
};

- 569
- 6
- 9