Reputation: 365
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.
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
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