Reputation: 1589
I am not able to retrieve the state
in the reducer
MyComponent looks like this
const MyComponent = ({name, features, onClick}) => {
return (
<div>
Hello! {name}
<Button onClick={() => { onClick(features); }}> Weight</Button>
</div>
);
const mapDispatchToProps = (dispatch: any) => {
return {
onClick: (features) => {
dispatch(weightSort(features));
}
};
};
const mapStateToProps = (state: any, ownProps: any) => {
console.log(state); //Displays the state
return {
name: "John Doe",
features: ownProps.features,
};
};
export const FeatureBlock = connect(mapStateToProps, mapDispatchToProps)(MyComponent);
My actions and reducers looks like below:
// Action Creator
export const weightSort = (features) => {
console.log("inside the weight sort action creator!!!");
return {
type: "SET_WEIGHT_FILTER",
filter: "DESC",
features,
};
};
// Reducer
export const weightFilter = (state = [], action) => {
switch (action.type) {
case "SET_WEIGHT_FILTER":
console.log(state); // Gives me empty state
console.log("++inside weight filter+++++", action); //Displays action
return state;
default:
return state;
}
};
export const FeatureBlock = connect(
mapStateToProps,
mapDispatchToProps,
)(MyComponent);
What am I missing here? Any help will be appreciated!
Upvotes: 1
Views: 785
Reputation: 5460
In your reducer, when you console.log(state)
, it is correct in returning an empty array because you haven't done anything to modify it.
// Reducer
export const weightFilter = (state = [1,2,3], action) => {
switch (action.type) {
case "SET_WEIGHT_FILTER":
console.log(state); // This will show [1,2,3] because [1,2,3] is the initial state.
console.log("++inside weight filter+++++", action); //Displays action
return state;
default:
return state;
}
};
My guess is that you want something like this for your reducer:
// Action Creator
export const weightSort = (name, features) => {
console.log("inside the weight sort action creator!!!");
return {
type: "SET_WEIGHT_FILTER",
name,
features,
};
};
// Reducer
export const weightFilter = (
state = {
name: '',
features: [],
},
action
) => {
switch (action.type) {
case "SET_WEIGHT_FILTER":
return {...state, name: action.name, features: action.features}
default:
return state;
}
};
and then in your mapStateToProps
you would map out the attributes like so:
const mapStateToProps = (state: any, ownProps: any) => {
console.log(state); //Displays the state
return {
name: state.weightFilter.name,
features: state.weightFilter.features,
};
};
and your button would have a name prop passed into the function like so:
<Button onClick={() => { onClick(name, features); }}> Weight</Button>
If you would like to sort your data, you can do so either in the reducer or inside the container. I prefer to do it in the container and like to use the lodash sortBy
function. It works like this:
import { sortBy } from 'lodash' //be sure to npm install lodash if you use this utility
...
...
function mapStateToProps(state) {
return {
name: state.weightFilter.name,
features: sortBy(features, ['nameOfPropertyToSortBy'])
};
}
Here is the lodash documentation on sortBy: https://lodash.com/docs/4.17.4#sortBy
Hope that helps!
Upvotes: 3