15

I am looking at thunk and trying to figure out how to implement an api call. It is not working so I have gone back to the very basics. When I click on the button it shows 'Getting here! in the console, but nothing is showing when I console.log(dispatch). Am I missing something here?

import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, applyMiddleware } from 'redux'; import { connect, Provider } from 'react-redux'; import thunk from 'redux-thunk' import axios from 'axis'; const store = createStore( reducer, applyMiddleware(thunk) ); function fetchUser() { return axios.get('https://randomuser.me/api/'); } function addUser() { console.log('Getting here'); return (dispatch) => { console.log(dispatch) //not showing anything return fetchUser().then(function(data){ console.log(data); }); }; } class App extends React.Component { addUser() { addUser(); } render() { return ( <button onClick={this.addUser.bind(this)}>+</button> ) } } const mapPropsToState = function(store){ return { newState: store } } var ConnectApp = connect(mapPropsToState)(App); ReactDOM.render( <Provider store={store}> <ConnectApp /> </Provider>, document.getElementById('app') ) 
2
  • @lux added this Commented Jan 10, 2017 at 16:44
  • 2
    Check mapDispatchToProps in redux Commented Jan 10, 2017 at 16:47

3 Answers 3

19

You cannot call addUser() from your component as a regular function. You have to use a mapDispatchToProps function and pass it to your connect call in order to be able to dispatch addUser().

const mapDispatchToProps = dispatch => ({addUser: () => dispatch(addUser())}) 

then

ConnectApp = connect(mapPropsToState, mapDispatchToProps)(App); 

Now you can call it as a prop.

addUser() { this.props.addUser(); } 
Sign up to request clarification or add additional context in comments.

Comments

4

You're not actually dispatching the thunk. You're calling it directly. You need to pass the inner () => {} thunk function to dispatch.

There's several ways to handle this. Since you're not providing a mapDispatchToProps argument to connect, the App component will automatically be given this.props.dispatch(). So, in App.addUser(), you could do this.props.dispatch(addUser()).

Another way would be to pre-bind the addUser action creator. You could do this with the syntax var ConnectApp = connect(mapPropsToState, {addUser})(App). Then, when you call this.props.addUser(), it will automatically dispatch the result.

I have some discussion on use of action creators and binding at http://blog.isquaredsoftware.com/2016/10/idiomatic-redux-why-use-action-creators/ , and a couple gists with sample code for binding and dispatching at https://gist.github.com/markerikson/6c7608eee5d2421966d3df5edbb8f05c and https://gist.github.com/markerikson/f46688603e3842af0f9720dea05b1a9e .

Comments

0

If you do not want to use connect function then you can use useDispatch() hook.

const dispatch = useDispatch(); useEffect(() => { dispatch(addUser()) }, []) 

You can use componentDidMount or UseEffect to fetch data.

Comments