React Redux : Action creator not calling reducer
The action creator does not call the reducer. It is what it is, nothing more, it creates an action - that is, an object with the action type and the payload for that action.
You need to dispatch an action, to force redux to call the reducer, and that is the place where you use your action creator, that is:
import { Dispatch } from "redux";
import { selectedFood } from "./actions";
Dispatch(selectedFood({type:"hamburger"}));
that should call the reducer, however mostly you'll not call the Dispatch
directly, rather in your mapDispatchToProps
method used to connect your react component to the redux store.
There are plenty of sample how to use react-redux
to use above map functionality, so I would suggest to read into it, and to read how redux works.
====== EDIT after question updated =========
So firstly dispatch from import is not used and ESLint is right telling it, you don't need that import since in:
const mapDispatchToProps = (dispatch) => {
console.log('IN mapDispatchToProps')
return {
onClick: ({data}) => {
dispatch(selectedFood({data}))
}
}
}
you don't call dispatch
from your import
only from the argument, it's passed to your mapDispatchToProps
by the connect
function.
Then this is just plain wrong:
<tr onClick={() => selectedFood({data})}>
you imported an action creator which is called on click of table row, that is an action definition is created by the action creator, and that's it. Your code does exactly what you wrote.
The mapDispatchToProps
function does what the name suggests - it maps dispatch functions to props of your component.
So it should be:
<tr onClick={() => this.props.onClick({data})}>
and that should dispatch the action and work.
However I would strongly suggest to take some courses or read more about react
, redux
and react-redux
, because your code samples and the question itself suggest, that you are just trying to get something to work, without the basic understanding how it works, and even how javascript works. Sorry for that comment but that's how it looks like.
kennedy
Updated on June 05, 2022Comments
-
kennedy almost 2 years
My action creator is not calling my reducer. Any help will be much appreciated.
types.js
export const SELECTED_FOOD = 'selected_food';
index.js (action creator / action)
import { SELECTED_FOOD } from './types'; export function selectedFood({data}) { console.log('SELECTED_FOOD **********************',data); return({ type: SELECTED_FOOD, payload: data }); }
Output from console.log in action creator
Object {_id: "18240", description: "Croissants, apple", score: 0.75, fields: Object}
selected_food_reducer.js
import { SELECTED_FOOD } from '../actions/types'; export default function(state = [], action) { switch(action.type) { case SELECTED_FOOD: console.log('Selected Food Reducer *************', state); return action.payload ; } return state; }
EDIT component failing to call dispatch.
I should have added this on my initial post, it appears there is something wrong in how dispatch is called. ESLint is flagging dispatch on line 3 for defined but never used.
import React from 'react'; import { connect } from 'react-redux'; import { dispatch } from 'react-redux'; import { selectedFood } from '../actions/index'; class TableRow extends React.Component { render() { const { data } = this.props; console.log('PROPS TableRow', this.props); const row = data.map((data) => <tr onClick={() => selectedFood({data})}> <td key={data.description}>{data.description}</td> <td key={data.id}>{data.fields.nutrients[0].amountPer100G}</td> <td key={data.id}>{data.fields.nutrients[1].amountPer100G}</td> <td key={data.id}>{data.fields.nutrients[4].amountPer100G}</td> </tr> ); return ( <tbody>{row}</tbody> ); } } const mapStateToProps = (state) => { return { selectedFood: state.selectedFood } } const mapDispatchToProps = (dispatch) => { console.log('IN mapDispatchToProps') return { onClick: ({data}) => { dispatch(selectedFood({data})) } } } export default connect(mapStateToProps, mapDispatchToProp)(TableRow);
-
kennedy about 7 yearsThank you Alek, I was not importing dispatch originally, but after doing so, it still does work and ESLint is flagging it for being declared but never used. I believe there is something incorrect in mapDispatchToProps, but I am failing to see it.
-
alek kowalczyk about 7 yearsEdited my answer.
-
kennedy about 7 yearsThank you Alek, thats good advice. I went through and read the redux documentation again last night and found the issue. It helped clear up a lot. I was going to update my post. Thanks again for your help =)
-
alek kowalczyk about 7 yearsIf my post helped you, feel free to mark it as an answer :-)
-
Sathish Sundharam over 5 yearsNice explanation from @alekkowalczyk
-
Brady Dowling almost 5 yearsThis was exactly it for me. I was calling the action from somewhere outside of a React component so I had to call dispatch directly on that action call and then it worked:
ReduxStore.dispatch(myaction());