#reactjs
#reactjs
Вопрос:
Мне нужно запретить пользователю добавлять имена, которые уже существуют в списке пользователей, но я не уверен, куда мне его добавить, а также какой метод лучше использовать .includes или indexOf ? Я хочу выдавать предупреждение с помощью команды alert при попытке такого действия. Любая помощь была бы очень кстати!
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
Комментарии:
1. Ни один из этих методов массива не принимает обратный вызов, что делает невозможным (насколько я знаю) использовать его для проверки существования на основе свойства объекта. Я бы посоветовал изучить
find
.
Ответ №1:
Вам нужно что-то сделать в следующем месте:
const addName = (event) => {
event.preventDefault();
const nameObject = {
name: newName
};
setPersons([...persons, nameObject]);
};
Используйте .find()
в persons
массиве, чтобы найти конкретное имя, которое уже существует, и добавить условие перед setPersons
выполнением.
if (persons.find(p => p.name === newName)) {
window.alert("Name already exists!");
return false;
}
Код, подобный приведенному выше, будет работать.
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;
Демонстрация: https://codesandbox.io/s/nervous-poitras-i3stw?file=/src/App.js:0-958
Приведенный выше код показывает уродливое предупреждение об ошибке, используя обычное оконное предупреждение. Если вам нужна лучшая ошибка, подобная этой:
Вы можете использовать следующий код, установив состояние:
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 amp;amp; <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;
И вот наш style.css
:
.error {
background-color: red;
color: #fff;
padding: 5px;
}
Демонстрация: https://codesandbox.io/s/vibrant-tree-wsou2?file=/src/App.js
Ответ №2:
Сначала добавьте поле, чтобы проверить, существует имя или нет:
const nameExists = React.useMemo(() => {
return persons.some(item => item.name === newName);
}, [newName, persons])
Затем отключите кнопку и покажите сообщение, если имя существует:
<div>
{nameExists amp;amp; <p>Name {newName} already exists!</p>}
<button type="submit" disabled={nameExists} >add</button>
</div>
Кроме того, убедитесь, что вы очистили имя при добавлении нового имени:
const addName = (event) => {
...
setNewName('')
}
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 amp;amp; <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'))
<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>
Ответ №3:
Вы можете использовать метод find для поиска пользователя с newName
помощью . Пожалуйста, проверьте приведенный ниже фрагмент кода:
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])
}
}
Комментарии:
1. Не добавляйте пустые ссылки изолированной среды