Задать вопрос
@livd98

Почему не перерисовывается компонент при изменении стейта?

Вывожу список из кубиков, хочу менять их местами перетягивая друг на друга через drag, всё работает, но только в консоль логе, сам же список кубиков не перерисовывается, хоть я и меняю стейт списка. Проблема где то в dragDropHandler. На typescript внимания не обращайте
6352ba897f220219214914.jpeg
import React, {useState} from 'react'
import './App.css'

interface ICurrentCard {
  currentCard: any;
}

export const App = () => {
  const [cardList, setCardList] = useState([
    {id: 1, text:' card number 1'},
    {id: 2, text:' card number 2'},
    {id: 3, text:' card number 3'},
    {id: 4, text:' card number 4'},
  ])
  const [currentCard, setCurrentCard] = useState<ICurrentCard | any> (null)

  const dragOverHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    e.preventDefault()
    e.target.style.background = 'lightgray'
  }

  const dragLeaveHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    e.target.style.background = 'red'
  }

  const dragDropHandler = (e: React.ChangeEvent<HTMLInputElement>, card: any) => {
    e.preventDefault()
    const newCardList = cardList.map(item => {
      if(item.id === card.id) {
        cardList.splice(card.id - 1, 1, currentCard)
      }
      if(item.id === currentCard.id) {
        cardList.splice(currentCard.id -1, 1, card)
      }
      return item
    })
    setCardList(newCardList)
    e.target.style.background = 'red'
  }
  
  const dragStartHandler = (card: any) => {
    setCurrentCard(card)
  }
  return (
    <div>
      {cardList.map(item => (
        <div 
          key={item.id}
          className='test'
          draggable={true}
          onDragOver={(e: any) => dragOverHandler(e)}
          onDragLeave={(e: any) => dragLeaveHandler(e)}
          onDrop={(e: any) => dragDropHandler(e, item)}
          onDragStart={(e: any) => dragStartHandler(item)}
        >
          <div>{item.id}</div>
          <div>{item.text}</div>
        </div>
      ))}
    </div>
  )
}
  • Вопрос задан
  • 129 просмотров
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Merion Academy
    Frontend-разработка на React
    4 месяца
    Далее
  • ProductStar
    React: отточите навыки интерфейсной разработки
    6 недель
    Далее
Решения вопроса 1
@SunUp
Я не волшебник, я ещё только учусь
В общем, у вас тут сразу несколько ошибок. Вот исправленный работающий пример, а теперь подробнее:
  1. Метод массивов splice изменяет исходный массив, и категорически не стоит использовать его напрямую на стейте, только на копии в коллбеке, это может приводить к весёлым ошибкам и увлекательному их поиску
  2. Цикл в вашем примере был абсолютно ни к чему, если вы использовали метод splice, который принимает напрямую индекс элемента для удаления/замены, тем более map, так как вы в нём возвращали item не изменяя его
  3. Даже при условии исправления предыдущих ошибок ваш пример корректно работать не будет так как после первого же перемещения id элемента больше не будет равен его текущему индексу в массиве, а вы пытаетесь из него получить это индекс
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽