Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 添加未添加到播放列表的歌曲_Reactjs_Redux_React Redux - Fatal编程技术网

Reactjs 添加未添加到播放列表的歌曲

Reactjs 添加未添加到播放列表的歌曲,reactjs,redux,react-redux,Reactjs,Redux,React Redux,在我的应用程序中 有一个组件可以渲染(播放)列表 (我有两个硬编码的列表) 我可以将新列表添加到列表列表中。 当你点击一个列表 将显示歌曲列表,列表底部是 一个按钮,当您单击它时,它会显示一个带有输入(标题、艺术家、相册)的表单。 在我修复添加列表功能之前,歌曲已添加到“活动”列表中 但是现在 该操作被调度(ADD_SONG)并在(Redux)状态下显示正确的值,但它呈现与列表相同类型的元素/组件,并且未被添加/添加。。。 我不知道该去哪里找 我希望有人能发现我的错误逻辑 AddSongForm

在我的应用程序中 有一个组件可以渲染(播放)列表 (我有两个硬编码的列表) 我可以将新列表添加到列表列表中。 当你点击一个列表 将显示歌曲列表,列表底部是 一个按钮,当您单击它时,它会显示一个带有输入(标题、艺术家、相册)的表单。 在我修复添加列表功能之前,歌曲已添加到“活动”列表中 但是现在
该操作被调度(ADD_SONG)并在(Redux)状态下显示正确的值,但它呈现与列表相同类型的元素/组件,并且未被添加/添加。。。 我不知道该去哪里找 我希望有人能发现我的错误逻辑

AddSongForm

export default class AddSongForm extends React.PureComponent {
  constructor() {
      super();

      this.state = {
        clicked: false
      };

      this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
      this.setState({
        clicked: !this.state.clicked
      })
    }

  handleChange = (event) => {
    const value = event.target.value
    const name = event.target.name
// console.log(name, value)
// console.log(this.state);
    this.setState({
      [name]: value
    })
  }

  handleSubmit = (event) => {
    event.preventDefault()
console.log(this.state);
    if (this.state.title && this.state.artist) {
      this.props.addSong({
        title: this.state.title,
        artist: this.state.artist,
        album: this.state.album
      })
    }
  }

  render() {

    return (<div>
      <button onClick={this.handleClick}><h2>New Song+</h2></button>

  {this.state.clicked ?
     <form onSubmit={this.handleSubmit}>
        <label>
          Song Title:
          <input type="text" name="title" onChange={this.handleChange} />
        </label>
        <label>
        <br/>  Artist:
          <input type="text" name="artist" onChange={this.handleChange} />
        </label>
        <label>
        <br/>  Album:
          <input type="text" name="album" onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
      : null}
    </div>)
  }

}
播放列表组件映射列表中的所有歌曲

export default class PlayList extends React.Component{
  constructor() {
      super()

      this.state = {
        clicked: false
      }
      this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
      this.setState({
        clicked: !this.state.clicked
      })
      console.log(this.props.selectList.name)

    }


render(){
  // console.log(this.props);
// console.log(this.props.playLists[0].data);
  return (<div>
    <button  onClick={this.handleClick}><h1>{this.props.playLists.title}</h1></button>
{this.state.clicked ?
  <ul>
      { this.props.playLists.data.map(song =>
        <li key={song.id} onClick={() => this.props.selectSong(song.id)}>
          <b>{song.title}</b><br/>
            By:
            <br/>
            <h3><b>{song.artist}</b></h3><br/>
             Appears on:
              <b>{song.album}</b><br/><br/>
        </li>
      ) }
      <AddSongFormContainer/>
    </ul>


     : null}


  </div>)
  }
}
导出默认类播放列表扩展React.Component{
构造函数(){
超级()
此.state={
单击:false
}
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
这是我的国家({
单击:!this.state.clicked
})
console.log(this.props.selectList.name)
}
render(){
//console.log(this.props);
//console.log(this.props.playLists[0].data);
返回(
{this.props.playLists.title}
{this.state.clicked?
    {this.props.playLists.data.map(歌曲=>
  • this.props.selectSong(song.id)}> {song.title}
    作者:
    {song.artist}
    出现在: {song.album}

  • ) }

    您的评论描述了您的redux问题,以及redux开发工具的屏幕截图-现在问题已经清楚了

    添加歌曲时,只需将其添加到商店的顶层,而不实际将其添加到播放列表中

    完全可以按原样修复此问题。在reducer中,您需要专门将歌曲添加到播放列表中,而不是像现在这样添加歌曲。如果您需要代码示例,我可以提供一个

    但是,我鼓励您重构redux应用商店,并遵循拥有

    这意味着,您希望为redux存储区提供两个顶级对象

    playlists
    songs
    
    您只需引用歌曲的id,而不是将歌曲的所有数据都包含在播放列表中

    您的播放列表如下所示:

    playlists { 
      1: {
      title: 'my playlist'
      songs: [1,2,3]}
    
    歌曲可以保持不变

    每当您向播放列表中添加歌曲时,只需添加歌曲,然后使用新的歌曲id更新播放列表

    为了使代码更简洁,您可以做的另一个实践是使用mapDispatchToProps,而不是内联定义redux操作分派

    # 要按原样修复代码,我们需要做的主要事情是传递您要将歌曲添加到的playlid。否则,我们如何知道将歌曲放在何处

    首先,更新addSongFormContainer中的操作,以接受另一个参数targetPlaylist(歌曲将进入该参数)

    使用此操作现在需要您传递目标播放列表。为简洁起见,我将对歌曲添加到播放列表1进行硬编码。将所选播放列表下传给组件的操作留给您自己完成

    我清理了handleSubmit以使其更清晰,方法是将歌曲移动到它自己的变量中

      handleSubmit = (event) => {
      event.preventDefault()
      console.log(this.state);
    
      if (this.state.title && this.state.artist) {
    
        let song = {
          title: this.state.title,
          artist: this.state.artist,
          album: this.state.album
        }
        let selectedPlayList = 1 //Fix this later :)
        this.props.addSong(song, selectedPlayList)
      }
    }
    
    最后一个问题是减速器

    case 'ADD_SONG':
          const index = store.getState().findIndex(playlist => playlist.id === 
            action.payload.playlist)
          console.log(index) //This should be index 0, after looking up playlist id: 1
          const updatedPlaylistSongs = this.state[index].data
          updatedPlaylistSongs.push(action.playload.song)
          return [
            ...state.slice(0, index), // All playlists before current
            {
              ...state[index], //The targeted playlist.
              ...updatedPlaylistSongs //The updated songs
            },
            ...state.slice(index + 1), //All playlists after current
        ]
    
    我希望reducer适合您,尽管它可能需要一些工作-我不习惯编写处理数组的reducer。我通常有规范化的数据,这会导致更容易的修改。我强烈建议您尝试规范化redux存储。停止使用数组,尝试使用生成密钥的对象(使用uuidv4生成唯一的随机键)。这使得“选择”要编辑/更新的内容变得非常容易


    我希望这有帮助!

    “在(Redux)状态下显示正确的值”-我假设您是通过redux开发工具看到这一点的?如果redux中的一切都正常工作,您的问题可能在于歌曲列表的显示。您能否发布负责显示歌曲的react组件/容器的代码?添加了播放列表组件,其中我映射了列表中的歌曲,并添加了播放列表容器w在这里,我映射了列表。我应该补充的是,redux中的一切都不正常,它会发送动作,并在我的检查器中显示Addu_SONG。在这种状态下,我有播放列表(一个数组,最初包含2个播放列表),它被添加到该数组中(我猜是作为播放列表),但播放列表有as键id、标题和数据(数组)值(标题、艺术家、专辑)应该进入数据列表我在我的答案中添加了一个大的更新,这个更新包含了新的action&reducer的逻辑。希望它有帮助!谢谢你,这是一个非常有用的答案。你能提供一个代码片段,说明我如何将它添加到播放列表中,专门用代码来解决它吗?就像中一样,因为我刚刚开始学习React-Redux,我不是really确定在减速器中实现逻辑的位置谢谢您,先生!我知道您在reducer中正在做什么,尽管它给了我一个类型错误:无法读取undefined的属性'findIndex',可能是因为我不确定应该在addsongform中为selectedPlayList提供什么..我尝试了几种方法this.state.playlist//this.props.selectList..事情是我有点动摇react redux中所有内容的连接方式我将在规范化我的数据(和存储等)时明确阅读抱歉,我认为这实际上是我的错。this.state是访问react容器中的状态。它需要是getState().findIndex访问reducer内部的redux存储。我还修复了上面示例中的代码。未定义提供getState()的代码:)
    playlists { 
      1: {
      title: 'my playlist'
      songs: [1,2,3]}
    
      addSong = (song, targetPlaylist) => {
    this.props.dispatch({
      type: 'ADD_SONG',
      payload: {
        playlist: targetPlaylist
        id: Math.ceil(Math.random()*10000),
        ...song
        }
      })
    }
    
      handleSubmit = (event) => {
      event.preventDefault()
      console.log(this.state);
    
      if (this.state.title && this.state.artist) {
    
        let song = {
          title: this.state.title,
          artist: this.state.artist,
          album: this.state.album
        }
        let selectedPlayList = 1 //Fix this later :)
        this.props.addSong(song, selectedPlayList)
      }
    }
    
    case 'ADD_SONG':
          const index = store.getState().findIndex(playlist => playlist.id === 
            action.payload.playlist)
          console.log(index) //This should be index 0, after looking up playlist id: 1
          const updatedPlaylistSongs = this.state[index].data
          updatedPlaylistSongs.push(action.playload.song)
          return [
            ...state.slice(0, index), // All playlists before current
            {
              ...state[index], //The targeted playlist.
              ...updatedPlaylistSongs //The updated songs
            },
            ...state.slice(index + 1), //All playlists after current
        ]