在本地保存和重新加载值的问题

Issue with Saving and Reloading a Value Locally

因此,在我的一个项目中,我试图添加将 Spotify API 中的曲目元素保存到会话中,然后再次提取它们的功能。我插入了一个控制台日志,发现即使会话存储中的元素未定义,它仍然会进入 checkPlaylistName() 方法中的 if 块。 render 语句中的控制台日志是 运行 两次,第一次,它传递了一个空数组,这是我在没有传递任何元素时想要的,第二次,由于某种原因,它传递了 undefined。这就是导致不同组件出错的原因,说它未定义传递。如果你需要整个 repo,你可以找到它 here。否则,这是导致问题的代码:

import React from 'react';
import './App.css';
import SearchBar from '../SearchBar/SearchBar';
import SearchResults from '../SearchResults/SearchResults';
import Playlist from '../Playlist/Playlist';
import Spotify from '../../util/Spotify.js';


class App extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   searchResults: [],
   playlistName: 'New Playlist',
   playlistTracks: [],
   term: ''
  }
  this.addTrack = this.addTrack.bind(this);
  this.removeTrack = this.removeTrack.bind(this);
  this.updatePlaylistName = this.updatePlaylistName.bind(this);
  this.savePlaylist = this.savePlaylist.bind(this);
  this.search = this.search.bind(this);
 }

 addTrack(track) {
  const addingTrack = (track) => this.setState({playlistTracks: [...this.state.playlistTracks, track]});
  addingTrack(track);
  this.removeTrack(track, false);
  sessionStorage.setItem("playlistTracks", this.state.playlistTracks);
 }

 removeTrack(track, removePlaylist) {
  if(removePlaylist) {
   const ids = this.collectIds(true);
   let trackIndex = -1;
   for(let i = 0; i < ids.length; i++) {
    if (ids[i] === track.id) {
     trackIndex = i;
    }
   }
   if (trackIndex !== -1) {
    const newPlaylist = this.state.playlistTracks;
    newPlaylist.splice(trackIndex, 1);
    this.setState({playlistTracks: newPlaylist});
    this.search(this.state.term);
   }
  } else {
   const ids = this.collectIds(false);
   let trackIndex = -1;
   for(let i = 0; i < ids.length; i++) {
    if (ids[i] === track.id) {
     trackIndex = i;
    }
   }
   if (trackIndex !== -1) {
    const newResults = this.state.searchResults;
    newResults.splice(trackIndex, 1);
    this.setState({searchResults: newResults});
   }
  }
  sessionStorage.setItem("playlistTracks", this.state.playlistTracks);
 }

 collectIds(removePlaylist) {
  let ids = [];
  if(removePlaylist) {
   this.state.playlistTracks.map(track => ids.push(track.id));
  } else {
   this.state.searchResults.map(track => ids.push(track.id));
  }
  return ids;
 }

 updatePlaylistName(name) {
  this.setState({playlistName: name});
  sessionStorage.setItem("playlistName", name);
 }

 savePlaylist() {
  let trackURIs = [];
  for(let i = 0; i < this.state.playlistTracks.length; i++) {
   trackURIs.push(this.state.playlistTracks[i].uri);
  }
  Spotify.savePlaylist(this.state.playlistName, trackURIs);
  this.setState({playlistName: 'New Playlist', playlistTracks: []});
  sessionStorage.removeItem("playlistTracks");
  sessionStorage.removeItem("playlistName");
 }

 async search(term) {
  const results = await Spotify.search(term);
  this.setState({searchResults: results});
  const resultIds = this.collectIds(false);
  const playlistIds = this.collectIds(true);
  let indexes = [];
  for(let i = 0; i < resultIds.length; i++) {
   for(let j = 0; j < playlistIds.length; j++) {
    if (resultIds[i] === playlistIds[j]) {
     indexes.push(i);
    }
   }
  }
  if(indexes.length > 0) {
   for (let k = 0; k < indexes.length; k++) {
    results.splice(indexes[k], 1);
   }
  }
  this.setState({searchResults: results});
  this.setState({term: term});
 }

 checkTracks() {
  if (sessionStorage.getItem("playlistTracks") !== undefined) {
   const tracks = sessionStorage.getItem("playlistTracks");
   this.setState({playlistTracks: tracks});
  }
  return this.state.playlistTracks;
 }

 checkPlaylistName() {
  const savedName = sessionStorage.getItem("playlistName");
  if (savedName !== null || savedName !== undefined) {
   this.setState({playlistName: savedName});
   console.log("hi");
  }
  return this.state.playlistName;
 }

 render() {
  return (
   <div id="root">
      <h1>Ja<span className="highlight">mmm</span>ing</h1>
      <div className="App">
        <SearchBar onSearch={this.search} />
        <div className="App-playlist">
           <SearchResults searchResults={this.state.searchResults} onAdd={this.addTrack} onRemove={this.removeTrack} />
           {console.log(this.checkTracks())}
           <Playlist 
            playlistName={this.checkPlaylistName()}
            playlistTracks={this.checkTracks()}
            onRemove={this.removeTrack}
            onNameChange={this.updatePlaylistName}
            onSave={this.savePlaylist}
           />
        </div>
      </div>
   </div>
  );
 }
}

export default App;

setState 函数是异步的 (https://medium.com/@baphemot/understanding-reactjs-setstate-a4640451865b),因此您在 checkTracks 方法中返回旧状态。

解决方法: 不要在您的 checkTracks 方法中设置状态,使其成为:

if (sessionStorage.getItem("playlistTracks") !== undefined) {
    return sessionStorage.getItem("playlistTracks");
}
return [];

并在构造函数中使用此方法来定义状态。

同样,您在渲染函数中设置状态(通过 checkTracks 方法),这会导致无限循环。