Tengo un componente de formulario donde contiene un estado que debe actualizarse (en el cambio de entrada) y se ve así:
import { useState } from 'react'; export const Test = () => { const [state, setState] = useState({ name: 'khaled', age: 18 }) const handleInputChange = (e) => { let stateCopy = state for(let key in stateCopy) { if(key === 'name') { stateCopy[key] = e.target.value; } } setState(stateCopy); } return( <div> <span>Name</span> <input onChange={ handleInputChange } /> <span>{state.name}</span> </div> ) }y se importó en el componente de la aplicación
import { Test } from '../../components/Test'; function App() { return ( <Test /> ); } export default App;y cada vez que intento cambiar el nombre, no actualiza la interfaz de usuario
Para hacer que la entrada sea un componente controlado, se deben asignar tanto el value como onChange .
<input value={state.name} onChange={handleInputChange} /> La función handleInputChange se puede mejorar para asegurarse de que el estado se actualice de forma inmutable:
const handleInputChange = ({ target: { value } }) => { setState(prevState => ({...prevState, name: value})); }Esto no funciona porque su objeto "stateCopy" no es en realidad una copia, es el objeto de estado real. está configurando el estado en el mismo objeto, lo que hace que reaccione para pensar que el estado no cambió en absoluto.
en su lugar, debe copiar el estado de esta manera
const handleInputChange = (e) => { let stateCopy = {...state} state.name = e.target.value setState(stateCopy); }También debe tener en cuenta que, a menos que haya una buena razón para elegir el estado, en mi opinión, debe usar un useState separado para cada elemento en el estado, lo que da como resultado un estado mucho más simple
import { useState } from 'react'; export const Test = () => { const [name, setName] = useState('khalad') const [age, setAge] = useState(18) const handleInputChange = (e) => { setName(e.target.value) } return( <div> <span>Name</span> <input onChange={ handleInputChange } /> <span>{state.name}</span> </div> ) }simplemente hazlo así, funcionará
const handleInputChange = (e) => { setState({...state, name: e.target.value}) }