Je dois empêcher l'utilisateur de pouvoir ajouter des noms qui existent déjà dans la liste de personnes, mais je ne sais pas où dois-je l'ajouter et quelle méthode est préférable d'utiliser .includes ou indexOf? Je veux émettre un avertissement avec la commande alert lorsqu'une telle action est tentée. Toute aide serait très appropriée!
import React, { useState } from 'react'
const App = () => {
const [ persons, setPersons ] = useState([ { name: 'Arto Hellas' }])
const [ newName, setNewName ] = useState('')
const addName = (event) => {
event.preventDefault()
const nameObject = {
name: newName,
}
setPersons([...persons,nameObject])
}
const handleNameChange = (event) => {
setNewName(event.target.value)
}
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={addName} >
<div>
name: <input value={newName} onChange={handleNameChange} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
{persons.map(person => (
<p key={person.name}>{person.name}</p>
))}
</div>
)
}
export default App
3 Réponses :
Vous devez faire quelque chose à l'endroit suivant:
.error {
background-color: red;
color: #fff;
padding: 5px;
}
Utilisez .find() sur le tableau persons pour trouver le nom particulier déjà existant et ajoutez la condition avant que setPersons soit exécuté.
import React, { useState } from "react";
import "./styles.css";
const App = () => {
const [persons, setPersons] = useState([{ name: "Arto Hellas" }]);
const [newName, setNewName] = useState("");
const [error, setError] = useState(false);
const addName = (event) => {
event.preventDefault();
if (persons.find((p) => p.name === newName)) {
setError(true);
return false;
}
const nameObject = {
name: newName
};
setPersons([...persons, nameObject]);
};
const handleNameChange = (event) => {
setNewName(event.target.value);
};
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={addName}>
{error && <p className="error">User already exists.</p>}
<div>
name: <input value={newName} onChange={handleNameChange} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
{persons.map((person) => (
<p key={person.name}>{person.name}</p>
))}
</div>
);
};
export default App;
Un code comme ci-dessus fonctionnera.
import React, { useState } from "react";
const App = () => {
const [persons, setPersons] = useState([{ name: "Arto Hellas" }]);
const [newName, setNewName] = useState("");
const addName = (event) => {
event.preventDefault();
if (persons.find((p) => p.name === newName)) {
window.alert("Name already exists!");
return false;
}
const nameObject = {
name: newName
};
setPersons([...persons, nameObject]);
};
const handleNameChange = (event) => {
setNewName(event.target.value);
};
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={addName}>
<div>
name: <input value={newName} onChange={handleNameChange} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
{persons.map((person) => (
<p key={person.name}>{person.name}</p>
))}
</div>
);
};
export default App;
Démo: https://codesandbox.io/s/nervous-poitras-i3stw?file=/src/App.js:0-958
Le code ci-dessus montre une vilaine alerte d'erreur utilisant l'alerte de fenêtre normale. Si vous voulez une meilleure erreur comme celle-ci:
Vous pouvez utiliser le code suivant, en définissant un état:
if (persons.find(p => p.name === newName)) {
window.alert("Name already exists!");
return false;
}
Et voici notre style.css :
const addName = (event) => {
event.preventDefault();
const nameObject = {
name: newName
};
setPersons([...persons, nameObject]);
};
Démo: https://codesandbox.io/s/vibrant-tree-wsou2?file=/src/App.js
Vous pouvez utiliser la méthode find pour rechercher une personne avec le newName . Veuillez vérifier l'extrait de code ci-dessous:
const addName = (event) => {
event.preventDefault()
const nameObject = {
name: newName,
}
let personAlreadyExists = persons.find(person => person.name === newName);
if (personAlreadyExists) {
alert('Person with that name already exists');
// any other operations (like clearing user input in the form, etc..)
}
else {
setPersons([...persons, nameObject])
}
}
Ne pas ajouter de liens sandbox vides
Ajoutez d'abord un champ pour vérifier que le nom existe ou non:
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>
Puis désactivez le bouton et affichez le message si le nom existe:
const App = () => {
const [ persons, setPersons ] = React.useState([ { name: 'Arto Hellas' }])
const [ newName, setNewName ] = React.useState('')
const addName = (event) => {
event.preventDefault()
const nameObject = {
name: newName,
}
setPersons([...persons,nameObject]);
setNewName('')
}
const handleNameChange = (event) => {
setNewName(event.target.value)
}
const nameExists = React.useMemo(() => {
return persons.some(item => item.name === newName);
}, [newName, persons])
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={addName} >
<div>
name: <input value={newName} onChange={handleNameChange} />
</div>
<div>
{nameExists && <p>Name {newName} already exists!</p>}
<button type="submit" disabled={nameExists} >add</button>
</div>
</form>
<h2>Numbers</h2>
{persons.map(person => (
<p key={person.name}>{person.name}</p>
))}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))Assurez-vous également d'effacer le nom lorsque vous ajoutez un nouveau nom:
const addName = (event) => {
...
setNewName('')
}
<div>
{nameExists && <p>Name {newName} already exists!</p>}
<button type="submit" disabled={nameExists} >add</button>
</div>
const nameExists = React.useMemo(() => {
return persons.some(item => item.name === newName);
}, [newName, persons])
Aucune de ces méthodes de tableau n'accepte un rappel, ce qui rend impossible (pour autant que je sache) de l'utiliser pour vérifier l'existence en fonction d'une propriété d'objet. Je suggérerais de chercher dans
find.