Я пытаюсь добавить теги только к одному ученику, но сталкиваюсь с проблемой, когда он добавляет введенный тег ко всем ученикам. Все остальное, например, получение по URL-адресу, работает нормально.
Добавление только части фрагмента, чтобы предотвратить копирование и вставку?
const [ students, setStudents ] = useState([])
const [ tags, setTags ] = useState([])
const addTags = (event) => {
if (event.key === 'Enter' && event.target.value !== '') {
setTags([...tags, event.target.value])
event.target.value = ''
}
}
if (!isLoaded) {
return <div>Loading...</div>
} else {
return (
<div className='__main'>
<ul className='__list'>
{students.map((student) => (
<li className='__student' key = {student.id}>
<img src = {student.pic} alt='student' />
<div className='__student-info'>
<h1>{student.firstName} {student.lastName}</h1>
<div className='__student-details'>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>
Average: {student.grades.reduce((a, b) => parseInt(b) + a, 0) / student.grades.map((grade) => grade).length}%
</p>
<div className='__student-tags'>
<ul className='__student-tags-list'>
{tags.map((tag, index) => (
<li className='__student-tag-item' key = {index}>
<span>{tag}</span>
</li>
))}
</ul>
<input
className='__student-tag-input'
type='text'
placeholder='Add a tag'
onKeyPress = {(event) => addTags(event)}
autoFocus
/>
</div>
</div>
</li>
))}
</ul>
</div>
)
}
Вы добавляете все теги для всех учащихся в единый массив состояний tags
с помощью setTags([...tags, event.target.value])
. Вместо использования отдельного состояния tags
вы, вероятно, захотите добавить массив tags
для каждого ученика в массив students
. Используйте свойство student.id
, чтобы обновить соответствующие теги учащегося.
Пример:
Обновите обработчик addTags
, чтобы он принимал идентификатор студента и возвращал обратный вызов для получения события onKeyPress
. Сопоставьте предыдущее состояние students
с новым массивом и для соответствующего ученика с помощью id
неглубокого копирования объекта student
и добавления нового tag
в массив tags
. Обратите внимание, что это каррированная функция, которая закрывает значение студента id
в области обратного вызова.
const addTags = id => (event) => {
const { value: tag } = event.target;
if (event.key === 'Enter' && tag) {
setStudents(students => students.map(
student => student.id === id
? {
...student,
tags: [...(student.tags || []), tag],
}
: student
));
event.target.value = '';
}
};
Сопоставьте массив student.tags
вместо автономного состояния tags
. Передайте student.id
обработчику addTags
.
<div className='__main'>
<ul className='__list'>
{students.map((student) => (
<li className='__student' key = {student.id}>
<img src = {student.pic} alt='student' />
<div className='__student-info'>
<h1>{student.firstName} {student.lastName}</h1>
<div className='__student-details'>
...
<div className='__student-tags'>
<ul className='__student-tags-list'>
{student.tags?.map((tag, index) => ( // <-- map student.tags array
<li className='__student-tag-item' key = {index}>
<span>{tag}</span>
</li>
))}
</ul>
<input
className='__student-tag-input'
type='text'
placeholder='Add a tag'
onKeyPress = {addTags(student.id)} // <-- pass student.id
autoFocus
/>
</div>
</div>
</div>
</li>
))}
</ul>
</div>
Это сработало, большое спасибо! Можете ли вы пояснить, как работает student.tags?.map, а не только student.tags.map? Я заметил, что он вылетает только с student.tags.map.
@EricDaoNguyen Ах, кажется, я правильно предположил, что ваши students
элементы данных не включают любое tags
свойство. Необязательный оператор цепочки (?.
) разрешает доступ к потенциально нулевым/неопределенным свойствам без создания исключения. student.tags?.map
эквивалентно student.tags && student.tags.map
, другими словами, student.tags
должно быть правдивым, чтобы получить функцию .map
.
Только @EricDaoNguyen student.tags.map
разбился, потому что student.tags
не определен до того, как обработчик addTags
смог внедрить свойство tags
в данные students
.
См. Как спросить, а затем измените его, чтобы более подробно объяснить, что и как делает ваш компонент.