Reputation: 583
I'm having problems with this. I'm creating a small app with react redux.
In the code below is my app.js component. It was working fine until I tried to use the mapDispatchToProps function inside connect. The problem is that I cannot invoke the dispatch action on componentDidMount anymore. The actions that were in componentDidMount and that now are on mapStateToProps need to be called on comoponentDidMount. Any clues in how to do that?
import React, { Component } from 'react';
import './App.css';
import '../../node_modules/bootstrap/less/bootstrap.less';
import { Route } from 'react-router-dom'
import * as ReadableAPI from '../ReadableAPI'
import HeaderNavigation from './HeaderNavigation';
import TableBody from './TableBody';
import { connect } from 'react-redux';
import sortAsc from 'sort-asc';
import sortDesc from 'sort-desc';
import {
selectedCategory,
fetchCategoriesIfNeeded,
fetchPostsIfNeeded,
invalidateSubreddit,
orderPost
} from '../actions'
class App extends Component {
state = {
posts: []
}
componentDidMount() {
const { dispatch, selectedCategory, fetchCategories, fetchPosts} = this.props
//dispatch(fetchCategoriesIfNeeded(selectedCategory))
//dispatch(fetchPostsIfNeeded(selectedCategory))
}
orderByScoreAsc = (posts) => {
return posts.sort(sortAsc('voteScore'))
}
orderByScoreDesc = (posts) => {
return posts.sort(sortDesc('voteScore'))
}
render() {
const { navCategories, posts } = this.props
return (
<div>
<HeaderNavigation navCategories = {navCategories} />
<Route exact path="/" render={()=>(
<TableBody
showingPosts={posts}
/>)}
/>
</div>
);
}
}
function mapStateToProps ( state ) {
const { categories, posts } = state
return {
navCategories: categories.items,
posts: posts.items
}
}
function mapDispatchToProps (dispatch) {
return {
changeOrder: (data) => dispatch(orderPost(data)),
fetchCategories: (data) => dispatch(fetchCategoriesIfNeeded(data)),
fetchPosts: (data) => dispatch(fetchPostsIfNeeded(data))
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
Upvotes: 9
Views: 28183
Reputation: 36179
I modified your code to what I think will work. I also left comments.
class App extends Component {
state = {
posts: []
}
componentDidMount() {
// no need to use dispatch again. Your action creators are already bound by
// mapDispatchToProps. Notice also that they come from props
const { selectedCategory, fetchCategoriesIfNeeded, fetchPostsIfNeeded} = this.props;
fetchCategoriesIfNeeded(selectedCategory);
fetchPostsIfNeeded(selectedCategory);
}
//... the same
}
function mapStateToProps ( state ) {
//... the same
}
function mapDispatchToProps (dispatch) {
// when arguments match, you can pass configuration object, which will
// wrap your actions creators with dispatch automatically.
return {
orderPost,
fetchCategoriesIfNeeded,
fetchPostsIfNeeded,
}
}
Upvotes: 9
Reputation: 166
You just don't. The mapDispatchToProps does exactly what you are trying to do in your component. Instead of calling a dispatch you call the method that was provided to your component by connect. in your case:
componentDidMount() {
const { selectedCategory, fetchCategories, fetchPosts} = this.props;
fetchCategories(selectedCategory);
fetchPosts(selectedCategory);
}
Upvotes: 1
Reputation: 2302
In map to dispatch you have fetchCategories/fetchPosts so therefore you need to call them like this:
componentDidMount() {
const { dispatch, selectedCategory, fetchCategories, fetchPosts } = this.props
//Call like this instead of fetchCategoriesIfNeeded/fetchPostsIfneeded
//dispatch(fetchCategories(selectedCategory))
//dispatch(fetchPosts(selectedCategory))
}
You have this:
function mapDispatchToProps (dispatch) {
return {
changeOrder: (data) => dispatch(orderPost(data)),
fetchCategories: (data) => dispatch(fetchCategoriesIfNeeded(data)),
fetchPosts: (data) => dispatch(fetchPostsIfNeeded(data))
}
}
So you need to call fetchCategories/fetchPosts from your props instead of fetchCatIfneeded/fetchPostsifneeded
Upvotes: 5