简体   繁体   English

ComponentDidMount Redux-Saga操作不起作用

[英]ComponentDidMount redux-saga action not working

I have a react component that is fetching data from an api using axios in the ComponentDidMount() function. 我有一个React组件,它使用ComponentDidMount()函数中的axios从api提取数据。 For some reason, the request flow stops at LOAD_PLAYLISTS_REQ, instead of continuing onto LOAD_PLAYLISTS_SUCCESS. 由于某种原因,请求流在LOAD_PLAYLISTS_REQ停止,而不是继续到LOAD_PLAYLISTS_SUCCESS。

Though if I trigger the same through a button click, the flow does get the data from API and calls the action, LOAD_PLAYLISTS_SUCCESS. 尽管如果我通过单击按钮触发相同操作,则该流程确实会从API获取数据并调用操作LOAD_PLAYLISTS_SUCCESS。

Is there a way to fix this issue? 有没有解决此问题的方法?

sagas.js 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 减速器/ 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 动作/ index.js

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

playlisttiles.js 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));

I believe this problem occurs because the scripts referring to the sagas of your project have not been fully loaded. 我相信会发生此问题,因为引用项目的Sagas的脚本尚未完全加载。 Therefore, a possible solution would be to dispatch the action only after everything has been loaded, and can do the following: 因此,一种可能的解决方案是仅在加载完所有内容后才分派操作,并且可以执行以下操作:

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

As we can see above, even with the mounted component, the action is only triggered when the whole page is loaded, to ensure that all its sagas are loaded. 正如我们在上面看到的,即使使用已安装的组件,也仅在加载整个页面时才触发操作,以确保加载其所有的事件。 This works for me. 这对我有用。 ;) ;)

Here are 2 things that look off right off the bat 这是两件事看起来很快

  1. Remove the * in front of the yield in the watchRequest function. 删除watchRequest函数中yield前面的*
  2. import all from redux-saga/effects and change the rootSaga to 从redux-saga / effects导入all ,并将rootSaga更改为

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

Try these and see if your problem gets resolved 尝试这些,看看您的问题是否得到解决

Edit: 编辑:

Try changing the mapDispatchToProps to 尝试将mapDispatchToProps更改为

const mapDispatchToProps = { selectNewsPlaylist, getPlaylist }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM