Reputation: 9140
I want my component to have a boolean property called waiting
. I trigger changes on this property via the setWaiting
action creator. The only problem is that inside my component this property arrives nested inside a property of the same name:
In my component I want to be able to do:
{this.props.waiting}
... but right now what I have to is:
{this.props.waiting.waiting}
Action creator:
export const WAITING = "waiting";
export function setWaiting(isWaiting) {
return {
type: WAITING,
payload: isWaiting
};
}
In my component I call this action like this:
this.props.setWaiting(true); // or false depending the case
Reducers setup:
import { combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";
import waitingReducer from "./reducer-waiting"
const rootReducer = combineReducers({
form: formReducer,
waiting: waitingReducer
});
export default rootReducer;
Reducer:
import _ from "lodash";
import { WAITING } from "../actions";
export default function waitinReducer(state = {}, action) {
if (_.isUndefined(state.waiting)) {
return Object.assign({}, state, { waiting: false });
}
switch (action.type) {
case WAITING:
// This is irrelevant here because the problem happens before this
// ever gets called. Just left it here for completeness sake.
return Object.assign({}, state, { waiting: action.payload });
default:
return state;
}
}
Map state to props (which already comes with a "bad" state):
let mapStateToProps = state => {
// This prints { waiting: { waiting: false } }
// but I just want { waiting: false }
console.log(state)
return {
waiting: state.waiting
}
}
Some extra context:
react: 16.4.1
react-dom: 16.4.1
redux: 3.7.2
react-redux: 4.4.9
Upvotes: 0
Views: 59
Reputation: 2998
Basically the change you want should happen in the reducer. You're using a object as state and setting waiting property inside the object. If you want only that boolean value, use that boolean as the state object, like below.
export default function waitinReducer(state = false, action) {
// default initialisation is false
// if (_.isUndefined(state.waiting)) {
// return Object.assign({}, state, { waiting: false });
// }
switch (action.type) {
case WAITING:
// just return the payload
return action.payload;
default:
return state;
}
}
Try this and let me know whether this works for you. One concern I have is, it won't update the props, since it's boolean is primitive type and value is stored not the reference.
Easiest change is @SamVK answer
Upvotes: 1
Reputation: 3435
You could try mapping just that state:
let mapStateToProps = state => ({
waiting: state.waiting.waiting
})
That'll keep each reducer as an object but at least not give you that awkward repetitiveness in the props themselves.
Upvotes: 1