简体   繁体   中英

Flux + React.js - Callback in actions is good or bad?

Let me explain the problem that I've faced recently.

I have React.js + Flux powered application:

  • There is a list view of articles (NOTE: there are multiple of of different lists in the app) and article details view inside it.
  • But there is only one API endpoint per each list which returns array of articles.
  • In order to display the details I need to find article by id in array. That works pretty fine. I trigger action which makes request to server and propagates store with data, when I go to details screen then I just get the necessary article from that array in store.
  • When user lands on article details view before list (stores are empty) then I need to make a request.
  • Flow looks like: User loads details view -> component did mount -> stores are empty -> rendered empty -> fetchArticles action is triggered -> request response is 200 -> stores now have list of articles -> component did update -> rendered with data successfully
  • Component could look as follows:

     let DetailsComponent = React.createClass({ _getStateFromStores() { let { articleId } = this.getParams(); return { article: ArticleStore.getArticle(articleId) }; }, componentDidMount() { // fire only if user wasn't on the list before // stores are empty if (!this.state.article) { ArticleActions.fetchArticles('listType'); } }, render() { return <ArticleDetails article={this.state.article} />; } }); 

The interesting part comes next:

  • Now I need to make another request to server but request options depend on the article details . That's why I need to make second request after the first one on the details view.
  • I've tried several approaches but all of them look ugly. I don't like calling actions from stores that makes stores too complicated. Calling action inside action in this case doesn't work well because I will need to find article from store inside that action.

Solution (?!)

  • What I've came up with is to use callback in action inside component and it feels much more cleaner:

     let DetailsComponent = React.createClass({ _getStateFromStores() { let { articleId } = this.getParams(); return { article: ArticleStore.getArticle(articleId) }; }, componentDidMount() { if (!this.state.article) { ArticleActions.fetchArticles('listType', () => { this._requestAdditionalData(); }); } this._requestAdditionalData(); }, _requestAdditionalData() { if (this.state.article) { ArticleActions.fetchAdditional(this.state.article.property); } }, render() { return <ArticleDetails article={this.state.article} />; } }); 

What's your input?

Consider move the second call to get a detail article to the ArticleDetails component componentDidMount() life cycle method.

So if the article is not set, do not render the ArticleDetails component at all by return null / false.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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