Обновление компонента, который не смонтирован, в соответствии с консолью - PullRequest
0 голосов
/ 04 июля 2019

Я получаю некоторые данные из базы данных, которая представляет собой массив объектов (песен). Я хотел бы показывать 5 песен за раз, потому что их более 800, и программа сильно замедляется, если я пытаюсь загрузить их все сразу.

Моя часть реагирования работает нормально, если я загружаю песни напрямую, но я пытаюсь создать другое состояние, в котором одновременно хранятся только 5 объектов, и отображать эти 5, а у меня есть другое состояние, называемое "песни", которое будет установите его состояние в начале, сохраняя более 800 песен. Когда я пытаюсь сохранить эти 5 в другом состоянии, программа вылетает.

Я ценю любую помощь в понимании моей ошибки.

Я попытался установить console.log внутри useEffect, которое изменяет showSongs, но esLint (я думаю, что это esLint) продолжает модифицировать массив в конце функции, добавляя в него некоторый код, который мне не нужен.

Я не могу сделать showSongs.map, но я могу сделать songs.map (но в песнях будет более 800 песен, поэтому я хочу показать showSongs).


function MySongsForm() {
  const [offset, setOffset] = useState({ quantity: 0 });
  const [showSongs, setShow] = useState([]);
  const [songs, setSongs] = useState([]);
  const [selectedSong, setSelected] = useState({ song: "" });
  const [recommendations, setRecommendations] = useState([]);

  useEffect(() => {
    async function getData() {
      const res = await requestMySongs();
      setSongs(res);
    }
    getData();
  }, [setSongs]);

  async function submitSong() {
    const recs = await recommendationRequest(selectedSong.song);
    setRecommendations(recs.tracks);
  }

  function UpdateSelected(event) {
    event.persist();
    console.log(event);
    console.log(event.target.value);
    setSelected({ song: event.target.value });
  }

  useEffect(() => {
    let newList = [];
    for (let i = offset.quantity; i < offset.quantity + 5; i++) {
      newList.push(songs[i]);
    }
    setShow(newList);
  }, [offset.quantity, setSongs, songs]);

  return (
    <div>
      <FormControl component="fieldset">
        <RadioGroup>
          {showSongs.map((song, index) => {
            return (
              <FormControlLabel
                control={<Radio />}
                key={index}
                value={song.song_spotify_id}
                name="songInput"
                onClick={e => UpdateSelected(e)}
                label={song.name}
              />
            );
          })}
        </RadioGroup>
        <Button onClick={() => submitSong()}>Select Song</Button>
      </FormControl>
      <DisplaySongs songs={recommendations} />
    </div>


  );
}


Ошибка, которую я получаю в браузере:

TypeError: Невозможно прочитать свойство 'song_spotify_id' из неопределенного

В консоли одновременно появляется ошибка:

Предупреждение. Невозможно выполнить обновление состояния React для отключенного компонента. Это не работает, но это указывает на утечку памяти в вашем приложении. Чтобы исправить, отмените все подписки и асинхронные задачи в функции очистки useEffect.

редактирование:

редактирование:

Я проверил, но я не знаю, что я ищу. Если я уберу следующую функцию, она будет работать:

  useEffect(() => {
    let newList = [];
    for (let i = offset.quantity; i < offset.quantity + 5; i++) {
      newList.push(songs[i]);
    }
    setShow(newList);
  }, [offset.quantity, setSongs, songs]);

Ответы [ 3 ]

0 голосов
/ 04 июля 2019

В вашем цикле for внутри useEffect вы добавляете +5 к offset.quantity:

for (let i = offset.quantity; i < offset.quantity + 5; i++) {
  newList.push(songs[i]);
}

Таким образом, он также выдвигает undefined элемент массива песен. Вы должны проверить, не перекрывается ли это с длиной массива:
Исправленная версия:

for (let i = offset.quantity; ((i < offset.quantity + 5) && (i < songs.length)); i++) {
  newList.push(songs[i]);
}
0 голосов
/ 04 июля 2019
  useEffect(() => {
    function setDisplay() {
      let newList = [];
      for (let i = offset.quantity; i < offset.quantity + 5; i++) {
        newList.push(songs[i]);
      }
      console.log(newList);
      setShow(newList);
    }
    if (songs.length !== 0) {
      setDisplay();
    }
  }, [offset, songs]);

Это решило это.

0 голосов
/ 04 июля 2019

Это происходит, когда у вас есть асинхронная функция, пытающаяся обновить ваше состояние после размонтирования компонента. Выполнение кода продолжается, пока ваш асинхронный обработчик, например, в ожидании ответа на сетевой запрос. В то время что-то уже привело к размонтированию вашего компонента.

Проверьте компонент рендеринга вашего MySongsForm. Что-то делает его размонтированным, прежде чем асинхронный обработчик внутри него пытается обновить состояние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...