首页 > 解决方案 > 在调用另一个动作创建者之前等待动作创建者完成 - Redux thunk

问题描述

我的应用程序中有 2 个动作创建者,名为 createPlaylist 和 fillPlaylist,为了调用 fillPlaylist,我必须先调用 createPlaylist 以获取播放列表的 id(fillPlaylist 中的 state.playlistDetail.id)。问题是当我调用fillPlaylist 时,createPlaylist 仍在获取数据,所以我无法调用fillPlaylist,因为state.playlistDetail.id 未定义。我想等到 createPlaylist 完成请求然后调用 fillPlaylist,我该如何实现呢?

创建播放列表

export const createPlaylist = () => async (dispatch, getState) => {
    const state = getState()
    let uris = []

    const data =  JSON.stringify({
        'name': 'Playlist Name',
        'description': 'Playlist description',
    })

    const response = await spotify.post(`/users/${state.user.id}/playlists`, data, {
        'headers' : {
            'Authorization': 'Bearer ' + state.token,
            'Content-Type': 'application/json'
        },
        
    })

    dispatch({type: 'CREATE_PLAYLIST', payload: response.data})

}

填充播放列表

export const fillPlaylist = (uris) => async (dispatch, getState) => {
    const state = getState()
    const data =  JSON.stringify({
        'uris': uris
    })
    console.log('state.playlistDetail', state)
    const response = await spotify.post(`/playlists/${state.playlistDetail.id}/tracks`, data, {
        'headers' : {
            'Authorization': 'Bearer ' + state.token,
            'Content-Type': 'application/json'
        },
        
    })

    dispatch({type: 'FILL_PLAYLIST', payload: response.data})
}

结果组件(这是我调用 createPlaylist 和 fillPlaylist 的地方)

import React, {Component} from 'react';
import { connect } from 'react-redux';
import { createPlaylist, fillPlaylist } from '../actions'

class Result extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    createPlaylist = () => {
        this.props.createPlaylist()

        let uris = []

        this.props.recommendations.forEach(item => { 
            uris.push(item.uri)
        })

        this.props.fillPlaylist(uris)
    }

    render() {

        return (
                <div>
                    <h1>Result</h1>
                    <button onClick={this.createPlaylist}>Create Playlist</button>
                </div>
            );
        
    }
}

const mapStateToProps = state => {
    return {recommendations: state.recommendations};
};

export default connect(mapStateToProps, {createPlaylist, fillPlaylist})(Result);

标签: reactjsreact-reduxspotifyredux-thunk

解决方案


您说您需要等待createPlaylist以完成获取数据,那么为什么不将 2 个函数合并为一个,如下所示:

export const createAndFillPlaylist = () => async (dispatch, getState) => {
  try {
    const state = getState();
    let uris = state.recommendations.map(item => item.uri);
    const PlayListBody = JSON.stringify({
      name: "Playlist Name",
      description: "Playlist description"
    });
    const headers = {
      Authorization: "Bearer " + state.token,
      "Content-Type": "application/json"
    };
    const { data } = await spotify.post(
      `/users/${state.user.id}/playlists`,
      PlayListBody,
      { headers }
    );
    dispatch({ type: "CREATE_PLAYLIST", payload: data });
    const createPlaylistBody = JSON.stringify({
      uris: uris
    });
    const response = await spotify.post(
      `/playlists/${data.id}/tracks`,
      createPlaylistBody,
      {
        headers
      }
    );
    dispatch({ type: "FILL_PLAYLIST", payload: response.data });
  } catch (error) {
    throw error;
  }
};

对于不需要的组件ToMapStateToProps,这是代码:

import React, { Component } from "react";
import { connect } from "react-redux";
import { createAndFillPlayList } from "../actions";

class Result extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div>
        <h1>Result</h1>
        <button onClick={this.props.createAndFillPlayList}>
          Create Playlist
        </button>
      </div>
    );
  }
}

export default connect(
  null,
  { createAndFillPlayList }
)(Result);

推荐阅读