根据控制台更新未安装的组件

时间:2019-07-04 13:00:21

标签: reactjs react-hooks use-effect

我正在从数据库中获取一些数据,该数据库是对象(歌曲)的数组。我想一次显示5首歌曲,因为有800多首歌曲,而且如果我尝试一次全部加载它们,那么程序的速度会大大降低。

如果直接加载歌曲,我的反应部分会正常工作,但是我试图创建另一个状态,一次仅存储5个对象,并显示这5个对象,而我有另一个状态称为“歌曲”,则该状态从一开始就将其设置为状态,存储800余首歌曲。当我尝试将这5种状态存储在另一种状态时,程序崩溃。

感谢您在理解我的错误方面的帮助。

我尝试在useEffect内设置console.log来修改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 :(得分:0)

当您有一个异步功能试图在卸载组件后更新状态时,会发生这种情况。当您的异步处理程序处于运行状态时,代码继续执行等待网络请求的响应。在那个时候,已经有一些事情导致您的组件卸下。

检查呈现MySongsForm的组件。在内部的异步处理程序尝试更新状态之前,有一些东西使其卸载。

答案 1 :(得分:0)

  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]);

这解决了。

答案 2 :(得分:-1)

useEffect内部的for循环中,您要向offset.quantity添加+5:

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

因此,它也同时推送了Songs数组的undefined元素。您必须检查它是否与数组长度不重叠:
更正的版本:

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