ComponentDidMount Redux-Saga操作不起作用

时间:2018-07-20 13:11:05

标签: javascript reactjs react-redux

我有一个react组件,它使用ComponentDidMount()函数中的axios从api提取数据。由于某种原因,请求流在LOAD_PLAYLISTS_REQ停止,而不是继续到LOAD_PLAYLISTS_SUCCESS。

尽管如果我通过单击按钮触发同样的操作,该流程确实会从API获取数据并调用操作LOAD_PLAYLISTS_SUCCESS。

是否可以解决此问题?

sagas.js

import { takeEvery, takeLatest } from 'redux-saga';
import { put, call } from 'redux-saga/effects'
import axios from 'axios';

export function* loadPlaylists({ payload }) {
    console.log("Loading Playlists");
    try {
        const response = yield call(axios.get, "http://localhost:5000/v1/browse/categories/trending/playlists");
        console.log(response);

        yield put({ type: 'LOAD_PLAYLISTS_SUCCESS', response }); // Yields effect to the reducer specifying the action type and user details
    } catch (error) {
        throw error;
    }
}

export function* watchRequest() {
    yield* takeLatest('LOAD_PLAYLISTS_REQ', loadPlaylists);
}

export default function* rootSaga() {
    yield [watchRequest()]
}

reducers / index.js

export default function(state = null, action) {
  console.log(action);
  switch (action.type) {
    case "LOAD_PLAYLISTS_SUCCESS":
      return action.response.data;
      break;
  }
  return state;
}

actions / index.js

export const getPlaylists = payload => {
  return {
    type: 'LOAD_PLAYLISTS_REQ',
    payload: payload
  }
}

playlisttiles.js

  class PlaylistTiles extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount() {
    this.props.getPlaylists("topstories");
  }

  handleClick(e) {
    e.preventDefault();
    this.props.history.push("/browse/1");
  }

  createPlaylist(newsItem) {
    return newsItem.articles.map(newsArticle => {
      return <li key={newsArticle.id}>{newsArticle.headline}</li>;
    });
  }

  createTiles() {
    return this.props.featuredNews.map(newsItem => {
      const {category} = this.props.category;
      return (
        <div
          key={newsItem.featuredId}
          className="card mb-4"
          onClick={() => this.props.getPlaylists(category)}
        >
          <img
            className="card-img-top"
            src="http://via.placeholder.com/150x150"
            alt="Card image cap"
          />
          <div className="card-body">
            <p>{newsItem.title}</p>
            <button onClick={this.handleClick}>Check Playlist</button>

            {/* <p className="card-text">{newsItem.articles[0].headline}</p>  */}
            {/* { this.createFeaturedPlaylist(newsItem) } */}
          </div>
        </div>
      );
    });
  }

  render() {
    const { playlist } = this.props;
    return (
      <Grid width={320} gap={4}>
        {this.createTiles()}
        {JSON.stringify(playlist)} 
      </Grid>
    );
  }
}


function mapStateToProps(state) {
  return {
    featuredNews: state.featuredNews,
    playlist: state.playlistItem
  };
}

function matchDispatchToProps(dispatch) {
  return bindActionCreators(
    {
      selectNewsPlaylist: selectNewsPlaylist,
      getPlaylists: getPlaylists
    },
    dispatch
  );
}

export default connect(
  mapStateToProps,
  matchDispatchToProps
)(withRouter(PlaylistTiles));

2 个答案:

答案 0 :(得分:2)

我相信会出现此问题,因为引用项目的sagas的脚本尚未完全加载。因此,一种可能的解决方案是仅在加载完所有内容后才分派操作,并且可以执行以下操作:

componentDidMount () {
     setTimeout (() => {
          this.props.getPlaylists("topstories");
      });
}

正如我们在上面看到的,即使使用已安装的组件,也仅在加载整个页面时才触发操作,以确保加载其所有的事件。这对我有用。 ;)

答案 1 :(得分:0)

这里有两件事情马上就消失了

  1. *函数中,将watchRequest移至收益率前面。
  2. 从redux-saga / effects导入all并将rootSaga更改为

export default function* rootSaga() { yield all [watchRequest()] }

尝试这些,看看问题是否得到解决

编辑:

尝试将mapDispatchToProps更改为

const mapDispatchToProps = { selectNewsPlaylist, getPlaylist }