Sigo teniendo un problema con mi aplicación CRUD cuando voy a editar un nombre de mi lista, arroja un error "Error de tipo: no se pueden leer las propiedades de undefined (leyendo 'nombre')".
Parece provenir del "valor = {usuario seleccionado. nombre}" en mi campo de entrada, pero cuando lo elimino, la aplicación compila pero no puedo modificar el campo en absoluto; no sucede nada cuando escribe. ¡Cualquier ayuda es apreciada!
import React, { useState, useContext, useEffect } from 'react' import { GlobalContext } from '../context/GlobalState' import { Link, useNavigate, useParams } from 'react-router-dom' import { Form, FormGroup, Label, Input, Button } from 'reactstrap' const EditUser = (props) => { const [selectedUser, setSelectedUser] = useState({ id: '', name: '' }); const { users, editUser } = useContext(GlobalContext); const navigate = useNavigate(); const currentUserId = useParams(props); useEffect(() => { const userId = currentUserId; const selectedUser = users.find(user => user.id === userId) setSelectedUser(selectedUser) }, [currentUserId, users]) const onSubmit = (e) => { e.preventDefault() editUser(selectedUser) navigate('/'); } const onChange = (e) => { setSelectedUser({...selectedUser, [e.target.name]: e.target.value}) } return ( <div> <Form onSubmit={onSubmit}> <FormGroup> <Label>Edit Name</Label> <Input type='text' name='name' value={selectedUser.name} onChange={onChange} placeholder='Enter Name'></Input> </FormGroup> <Button type='submit'>Edit Name</Button> <Link to='/' className='btn btn-danger m-2'>Back</Link> </Form> </div> ) } export default EditUserSi currentUserId no está undefined por algún motivo, o su users.find() devuelve undefined , entonces almacenará undefined en su variable de estado de usuario selectedUser .
Según sus comentarios, parece que no puede usar el encadenamiento opcional (la sintaxis foo?.bar ), entonces probablemente solo quiera evitar esto en la fuente:
useEffect(() => { const userId = currentUserId; const foundUser = users.find((user) => user.id === userId); if (foundUser) { setSelectedUser(foundUser); } }, [currentUserId, users]); También tenga en cuenta que cambié el nombre de su variable dentro de su useEffect para evitar confusiones con su usuario selectedUser en el nivel superior.
Array.prototype.find devuelve el primer elemento coincidente, o indefinido si no se encuentra dicha coincidencia.
const selectedUser = users.find(user => user.id === userId); // potentially undefined Además, el valor devuelto por el useParams es un objeto de los pares clave-valor de cualquier parámetro de ruta de ruta definido. El código parece asumir incorrectamente que el valor devuelto es el parámetro currentUserId de una ruta y lo usa para buscar en la matriz de users .
const currentUserId = useParams(props); useEffect(() => { const userId = currentUserId; const selectedUser = users.find(user => user.id === userId); setSelectedUser(selectedUser); }, [currentUserId, users]); Dudo que alguna vez pueda haber una coincidencia encontrada que compare user.id con el objeto params devuelto.
Sospecho que el parámetro de ruta real es realmente userId . O desestructurarlo inmediatamente desde el gancho useParams .
const { userId } = useParams(); o cambie el nombre de currentUserId a params y desestructurar userId en el enlace.
const params = useParams(props); useEffect(() => { const { userId } = params; const selectedUser = users.find(user => user.id === userId); setSelectedUser(selectedUser); }, [params.userId, users]); Un último punto sobre los parámetros de ruta y las propiedades de identificación. Los parámetros de ruta siempre serán de tipo cadena. A veces, la id es en realidad un tipo de número, por lo que querrá usar una verificación de igualdad de tipo seguro. Convertir identificadores en tipos de cadena, que cubre ambos identificadores de cadena y convertirá números en cadenas similares a números.
useEffect(() => { const { userId } = params; const selectedUser = users.find(user => String(user.id) === userId); setSelectedUser(selectedUser); }, [params.userId, users]);Protección contra valores nulos/indefinidos.
Primero, intente mantener un estado de usuario selectedUser estable e invariable. En otras palabras, no lo actualice con un valor indefinido a menos que tenga una necesidad específica. Verifique el resultado de users.find para ver si se encontró una coincidencia.
const { userId } = useParams(props); useEffect(() => { const selectedUser = users.find(user => String(user.id) === userId); if (selectedUser) { setSelectedUser(selectedUser); } }, [userId, users]);En segundo lugar, protéjase defensivamente contra accesos potencialmente nulos/indefinidos en su función de representación, por si acaso. Puede usar los operadores de encadenamiento opcional y coalescencia nula para proteger el acceso nulo y proporcionar un valor definido válido para la entrada controlada.
<Input type='text' name='name' value={selectedUser?.name ?? ""} onChange={onChange} placeholder='Enter Name' />o si prefiere los controles nulos/cláusulas de protección de la escuela anterior
<Input type='text' name='name' value={(selectedUser && selectedUser.name) ?? ""} onChange={onChange} placeholder='Enter Name' />