I have a parent component that is interested in gathering a list of contacts (name+email):
import { useState } from 'react'
import AddContactFn from './components/AddContactFn'
function App() {
const [contacts, setContacts] = useState([])
const addNewContact = (newContact) => {
setContacts([...contacts, newContact])
}
return (
<div>
<AddContactFn newContact={addNewContact} />
</div>
)
}
export default App
through a child component, which renders a form, with two inputs fields and an 'Add' button:
import React from 'react'
import { useState } from 'react'
export default function AddContactFn({ newContact }) {
const [contact, setContact] = useState({name: ' ', email: ' '})
const addContact = (e) => {
e.preventDefault()
if (contact.name === ' ' || contact.email === ' ') {
return
}
newContact(contact)
}
return (
<div>
<h2>Add Contact</h2>
<form onSubmit={addContact}>
<label>Name</label>
<input
type='text'
name='name'
value={contact.name}
placeholder='Name'
onChange={e => setContact({ name: e.target.value })}
/>
<label>Email</label>
<input
type='text'
name='email'
value={contact.email}
placeholder='Email'
onChange={e => setContact({ email: e.target.value })}
/>
<button type='submit'>Add</button>
</form>
</div>
)
}
I am facing two issues:
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.- with both input fields containing text, every time the Add button is pressed, only the last edited value is returned to the parent (ie. either 'name' or 'email' is returned, not both)