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);
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.