Добавление тега к одному элементу вместо всех элементов?

Я пытаюсь добавить теги только к одному ученику, но сталкиваюсь с проблемой, когда он добавляет введенный тег ко всем ученикам. Все остальное, например, получение по 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>
    )
  }

См. Как спросить, а затем измените его, чтобы более подробно объяснить, что и как делает ваш компонент.

isherwood 05.04.2022 20:51
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
33
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы добавляете все теги для всех учащихся в единый массив состояний 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.

Eric Dao Nguyen 06.04.2022 16:50

@EricDaoNguyen Ах, кажется, я правильно предположил, что ваши students элементы данных не включают любое tags свойство. Необязательный оператор цепочки (?.) разрешает доступ к потенциально нулевым/неопределенным свойствам без создания исключения. student.tags?.map эквивалентно student.tags && student.tags.map, другими словами, student.tags должно быть правдивым, чтобы получить функцию .map.

Drew Reese 06.04.2022 17:36

Только @EricDaoNguyen student.tags.map разбился, потому что student.tags не определен до того, как обработчик addTags смог внедрить свойство tags в данные students.

Drew Reese 06.04.2022 17:38

Другие вопросы по теме