reactjs - React .map 不更新数组中的数据

标签 reactjs

我遇到了这个问题,我的 .map 在重新渲染时不会更新任何数据。我有一个简单的播放器,它正在移动到 playlist 数组中的下一个元素,并且在更新后或每次我在播放器栏中单击下一个或上一个时,它应该显示所选歌曲的艺术家 {artist.name} 和所选歌曲 {song.name} 但由于某种原因没有任何变化。我想我错过了一些明显的东西,但看不到它有人可以帮我吗?谢谢。

const PlayerBar = (props) => {
  const [playing, setPlaying] = React.useState(false);

  function clickPlayButton() {
    setPlaying(!playing)
  }

  function renderPlayButton() {
    let buttonUrl = '';
    if (playing) {
      buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557137524244/rounded-pause-button.svg';
    } else {
      buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557136695174/play-right-arrow-circular-button.svg';
    }
    return (
      <input
        id="playPause"
        className="play-button"
        type="image"
        src={buttonUrl}
        onClick={() => clickPlayButton()}
      />
    );
  }

  function renderNextButton() {
    let buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557137539567/next-button.svg';
    return (
      <input
        id="next"
        className="play-button" 
        type="image" 
        src={buttonUrl} 
        onClick={() => props.nextButton()}
      />
    );
  };

  function renderPrevButton() {
    let buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557138446191/previous-button.svg';
    return (
      <input
        id="prev"
        className="play-button" 
        type="image"  
        src={buttonUrl} 
        onClick={() => props.prevButton()}
      />
    );
  };

  return (
      <div>
        {renderPlayButton()}
        {renderPrevButton()}
        {renderNextButton()}
        
        <div className="song-descr">
          <span className="song-artist song-span">Artist of the selected song</span>
          <span className="song-name song-span">Selected song name</span>
        </div>
      </div>
  );
}

const App = () => {
  const playlist = [
      {
        id: 1,
        name: 'Yesterday',
        artist: 'Beatles'
      },
      {
        id: 2,
        name: 'Nothing else matters',
        artist: 'Metallica'
      },
      {
        id: 3,
        name: 'Always',
        artist: 'Bon Jovi'
      },
      {
        id: 4,
        name: 'Waka Waka',
        artist: 'Shakira'
      }
    ];

  const [curItemIndex, setCurItemIndex] = React.useState(0);
    const [list, setPlaylist] = React.useState(playlist)

    
  function getSongClass(index) {
    let className = 'list-group-song song row';
    if (index === curItemIndex) {
      className += ' selected';
    }
    return className;
  }

  function renderItems() {
    return list.map((song, index) => {
      return (
        <li className={getSongClass(index)} key={song.id}>
          <span className="song-artist song-span">{song.artist}</span>
          <span className="song-name song-span">{song.name}</span>
        </li>
      );
    });
  }

  function clickNextButton() {
    if(curItemIndex === curItemIndex.length - 1)
        return;
        
    setCurItemIndex(curItemIndex => curItemIndex + 1)

  }

  function clickPrevButton() {
     if(curItemIndex === 0)
        return;
        
    setCurItemIndex(curItemIndex => curItemIndex - 1)
  }

  return (
    <div>
      <ul className="song-list container">
        {renderItems()}
      </ul>
      <hr />
      <div className="player-bar">
        <PlayerBar
          nextButton={clickNextButton}
          prevButton={clickPrevButton}
        />
      </div>
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

最佳答案

const PlayerBar = (props) => {
  const [playing, setPlaying] = React.useState(false);

  function clickPlayButton() {
    setPlaying(!playing)
  }

  function renderPlayButton() {
    let buttonUrl = '';
    if (playing) {
      buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557137524244/rounded-pause-button.svg';
    } else {
      buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557136695174/play-right-arrow-circular-button.svg';
    }
    return (
      <input
        id="playPause"
        className="play-button"
        type="image"
        src={buttonUrl}
        onClick={() => clickPlayButton()}
      />
    );
  }

  function renderNextButton() {
    let buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557137539567/next-button.svg';
    return (
      <input
        id="next"
        className="play-button" 
        type="image" 
        src={buttonUrl} 
        onClick={() => props.nextButton()}
      />
    );
  };

  function renderPrevButton() {
    let buttonUrl = 'https://codesignal.s3.amazonaws.com/uploads/1557138446191/previous-button.svg';
    return (
      <input
        id="prev"
        className="play-button" 
        type="image"  
        src={buttonUrl} 
        onClick={() => props.prevButton()}
      />
    );
  };

  return (
      <div>
        {renderPlayButton()}
        {renderPrevButton()}
        {renderNextButton()}
        
        <div className="song-descr" id={props.listId}>
          <span className="song-artist song-span">{props.listArtist}</span> // here ...
          <span className="song-name song-span">{props.listName}</span> // here ...
        </div>
      </div>
  );
}



const App = () => {
  const playlist = [
      {
        id: 1,
        name: 'Yesterday',
        artist: 'Beatles'
      },
      {
        id: 2,
        name: 'Nothing else matters',
        artist: 'Metallica'
      },
      {
        id: 3,
        name: 'Always',
        artist: 'Bon Jovi'
      },
      {
        id: 4,
        name: 'Waka Waka',
        artist: 'Shakira'
      }
    ];

  const [curItemIndex, setCurItemIndex] = React.useState(0);
    const [list, setPlaylist] = React.useState(playlist)

    
  function getSongClass(index) {
    let className = 'list-group-song song row';
    if (index === curItemIndex) {
      className += ' selected';
    }
    return className;
  }

  function renderItems() {
    return list.map((song, index) => {
      return (
        <li className={getSongClass(index)} key={song.id}>
          <span className="song-artist song-span">{song.artist}</span>
          <span className="song-name song-span">{song.name}</span>
        </li>
      );
    });
  }

  function clickNextButton() {
    if(curItemIndex === list.length - 1) // here ...
        return;
        
    setCurItemIndex(curItemIndex => curItemIndex + 1)

  }

  function clickPrevButton() {
     if(curItemIndex === 0)
        return;
        
    setCurItemIndex(curItemIndex => curItemIndex - 1)
  }

  return (
    <div>
      <ul className="song-list container">
        {renderItems()}
      </ul>
      <hr />
      <div className="player-bar">
        <PlayerBar
          nextButton={clickNextButton}
          prevButton={clickPrevButton}
          listId={list[curItemIndex].id} // here ...
          listName={list[curItemIndex].name} // here ...
          listArtist={list[curItemIndex].artist} // here ../
        />
      </div>
    </div>
  );
}


ReactDOM.render(
  <App />,
  document.getElementById('app')
);

请尝试这个。我只改变了 6 行

关于reactjs - React .map 不更新数组中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66547003/

相关文章:

javascript - React axios - 尽管使用箭头函数但仍丢失此上下文

css - 在方形和圆形按钮内将 fontawesome 组件与 faPlay 图标居中

reactjs - 如何在属性为 "true"时更改样式

javascript - Async.js 与 Gulp 变成错误 "Callback was already called"

ReactJS目录结构用于服务器和客户端之间以及不同客户端之间的代码共享

reactjs - 如何使用 React 正确编写条件类型?

javascript - 如何使用 es6 语法导入 ReactCSSTransitionGroup?

reactjs - Flow 需要 HOC 中 props 的类型注释

javascript - React-router中的path和url有什么区别

javascript - React 中如何让父组件管理子组件的状态?