Reacher
Reacher

Reputation: 365

Dispatch same action in event handler AND in ComponentDidUpdate?

recently I was learning the Redux + Redux thunk to deal with async actions. In the official tutorial about the Reddit API, I don't quite understand that why we need to dispatch fetchPostsIfNeeded(means fetch the posts if needed) multiple time.The Link is Official, and the online editor's Here.

In another post on StackOverflow, they've had discussion about this, but they only chose to use either event handler or componentDidUpdate, not using both the same time.

The Question is: in the official example, is it redundant to handle the dispatch action in componentDidUpdate(to fetch posts if update available) if there is already a handleChange and handleRefreshClick (to fetch posts if update available) in there ? I have attached the React life cycle here for better understanding.

Life Cycle in React

Code snippets for file AsyncApp.js:

class AsyncApp extends Component {
  constructor(props) {
    super(props)
    this.handleChange = this.handleChange.bind(this)
    this.handleRefreshClick = this.handleRefreshClick.bind(this)
  }

  componentDidMount() {
    const { dispatch, selectedSubreddit } = this.props
    dispatch(fetchPostsIfNeeded(selectedSubreddit))
  }

  componentDidUpdate(prevProps) {
  ^^^^^^^^^^^^^^^^^^
    if (this.props.selectedSubreddit !== prevProps.selectedSubreddit) {
      const { dispatch, selectedSubreddit } = this.props
      dispatch(fetchPostsIfNeeded(selectedSubreddit))
               ^^^^^^^^^^^^^^^^^^

    }
  }

  handleChange(nextSubreddit) {
  ^^^^^^^^^^^^
    this.props.dispatch(selectSubreddit(nextSubreddit))
    this.props.dispatch(fetchPostsIfNeeded(nextSubreddit))
                        ^^^^^^^^^^^^^^^^^^
  }

  handleRefreshClick(e) {
  ^^^^^^^^^^^^^^^^^^^^
    e.preventDefault()

    const { dispatch, selectedSubreddit } = this.props
    dispatch(invalidateSubreddit(selectedSubreddit))
    dispatch(fetchPostsIfNeeded(selectedSubreddit))
             ^^^^^^^^^^^^^^^^^^
  }

  render() {
    const { selectedSubreddit, posts, isFetching, lastUpdated } = this.props
    return (
      <div>
        <Picker
          value={selectedSubreddit}
          onChange={this.handleChange}
          options={['reactjs', 'frontend']}
        />
        <p>
          {lastUpdated && (
            <span>
              Last updated at {new Date(lastUpdated).toLocaleTimeString()}.{' '}
            </span>
          )}
          {!isFetching && (
            <button onClick={this.handleRefreshClick}>Refresh</button>
          )}
        </p>
        {isFetching && posts.length === 0 && <h2>Loading...</h2>}
        {!isFetching && posts.length === 0 && <h2>Empty.</h2>}
        {posts.length > 0 && (
          <div style={{ opacity: isFetching ? 0.5 : 1 }}>
            <Posts posts={posts} />
          </div>
        )}
      </div>
    )
  }
}

function mapStateToProps(state) {
  const { selectedSubreddit, postsBySubreddit } = state
  const { isFetching, lastUpdated, items: posts } = postsBySubreddit[
    selectedSubreddit
  ] || {
    isFetching: true,
    items: []
  }

  return {
    selectedSubreddit,
    posts,
    isFetching,
    lastUpdated
  }
}

export default connect(mapStateToProps)(AsyncApp)

Thank you

Upvotes: 0

Views: 309

Answers (1)

Fyodor Yemelyanenko
Fyodor Yemelyanenko

Reputation: 11848

In this exact sample componentDidUpdate is useless, as requests to update are made from inside event handler. But if you have additional component, say ThirdPartyUpdater which will present Picker somewhere in another place in SPA, componentDidUpdate will do it job to refetch posts.

I've modified provided demo to showcase this. Upper Picker is separate component from AsyncApp and it just update selectedSubreddit. AsyncApp then receives updated props and request new subreddit in componentDidUpdate.

From my point of view, it's better to put fetchPostsIfNeeded inside selectSubreddit action creator. Whenever we select new subreddit, we should immediately refetch posts. So separating these two steps may create bugs in future.

Upvotes: 1

Related Questions