así que tengo el problema en el que tengo el formulario de una guía telefónica y agrego personas en ella, pero la tarea es cada vez que intento agregar el usuario que ya está allí, no debe dejarme hacerlo y arrojar un error esta persona ya está en un directorio telefónico no quiero la única solución quiero una explicación si alguien me puede explicar cómo resolverlo y cómo funciona el código:
import React, { useState } from 'react' import Person from './Person' const App = () => { const [persons, setPersons] = useState([ ]) const [newName, setNewName] = useState('') const handleNoteChange = (event) => { setNewName(event.target.value) } const resetForm = () => { setNewName('') } const handleSubmit = (e) => { e.preventDefault() const persona = { name: newName, id:Math.floor(Math.random() * 10000) } setPersons(persons.concat(persona)) setNewName('') persons.map(perperson =>{ if(perperson.name === newName){ alert(`${newName} is already in the phonebook `) } }) console.log(persona); } return ( <div> <h2>Phonebook</h2> <form onSubmit={handleSubmit}> <div> name: <input value={newName} onChange={handleNoteChange} /> </div> <div> <button type="submit">add</button> </div> </form> <h2>Numbers</h2> <ul> {persons.map(person => { return( <Person key={person.id} name={person.name} /> ) })} </ul> <p onClick={resetForm}>reset input</p> <p>phonebook name is - {newName}</p> </div> ) } export default Appcomponente persona:
import React from 'react'; const Person = (props) => { return( <div> <li key ={props.id}>{props.name}</li> </div> ) }; export default Person;En la función de envío, primero debe verificar si el valor ya está allí o no. solo después de verificar empujarlo a la matriz original. en su método actual, está presionando el nombre antes de la verificación de validación. verifique los comentarios en el código para obtener más explicaciones
import React, { useState } from "react"; import Person from "./Person"; const App = () => { const [persons, setPersons] = useState([]); const [newName, setNewName] = useState(""); const handleNoteChange = (event) => { setNewName(event.target.value); }; const resetForm = () => { setNewName(""); }; const handleSubmit = (e) => { e.preventDefault(); //checking is the value already there in persons, if index return -1 //it means value is not there on the array and we can push newName to //array, if it return a value other than -1 it means the value already there in a index. if (persons.findIndex((p) => p.name == newName) != -1) { alert(`${newName} is already in the phonebook `); return; //This will stop further execution if function so that it will not push data } const persona = { name: newName, id: Math.floor(Math.random() * 10000) }; setPersons([...persons, persona]); //contacting array using spread opertaor setNewName(""); }; return ( <div> <h2>Phonebook</h2> <form onSubmit={handleSubmit}> <div> name: <input value={newName} onChange={handleNoteChange} /> </div> <div> <button type="submit">add</button> </div> </form> <h2>Numbers</h2> <ul> {persons.map((person) => { return <Person key={person.id} name={person.name} />; })} </ul> <p onClick={resetForm}>reset input</p> <p>phonebook name is - {newName}</p> </div> ); }; export default App;Aquí hay una demostración en funcionamiento https://codesandbox.io/s/stoic-hofstadter-f402o?file=/src/App.js
Debe implementar su lógica de validación antes de insertar a la persona en la matriz, en este momento su código está realizando la validación después de haber insertado a la persona, por lo tanto, nunca evitará una entrada repetida.
const handleSubmit = (e) => { e.preventDefault() const persona = { name: newName, id:Math.floor(Math.random() * 10000) } //Here you are inserting the person into the persons array and setting the newName to '', //that won't allow you to use newName later in order to perform any kind //of validation. You should set newName to '' once you've already validated if the //provided user is part of the array. setPersons(persons.concat(persona)) setNewName('') //Here you are validating if the person is already part of the array //You should do this before the insertion process. persons.map(perperson =>{ if(perperson.name === newName){ alert(`${newName} is already in the phonebook `) } }) Además, no es necesario usar el map para realizar el proceso de validación, ya que el map itera sobre la matriz y devuelve los elementos que cumplen la condición especificada (eso no lo ayudará en este caso particular). Debería usar el método some en su lugar y mantener la misma lógica de validación; devuelve verdadero si un elemento cumple con la condición esperada y falso de lo contrario, eso le permitirá verificar si, de hecho, el elemento que está tratando de insertar ya es parte de la matriz. Terminarás con el siguiente resultado:
const handleSubmit = (e) => { e.preventDefault() const persona = { name: newName, id:Math.floor(Math.random() * 10000) } let alredyInRegister = persons.some(perperson =>{ if(perperson.name === newName){ return true; } return false }) if (alreadyInRegister) { alert(`${newName} is already in the phonebook `) } else { setPersons(persons.concat(persona)) setNewName('') } }