Reputation: 302
So I'm learning react and redux and I get this error in the console whenever I load my page. I'm not sure what it means since my store should be connected properly (as far as I know, but obviously it's not).
Warning: Failed prop type: The prop
open
is marked as required in >Navigation
, but its value isundefined
.
This is component (shortened to the key parts I think)
Navigation.propTypes = {
open: PropTypes.bool.isRequired,
};
const mapStateToProps = (state: any) => ({
open: state.open,
})
export default connect(mapStateToProps, { shiftContent })(Navigation);
My action
export const shiftContent = (open: boolean) => {
return {
type: ContentTypes.SHIFT_CONTENT,
payload: open
}
}
My Reducer:
const initialState = {
open: false,
};
export default function(state = initialState, action: IAction) {
switch(action.type) {
case ContentTypes.SHIFT_CONTENT:
console.log("shifting Open = " + action.payload);
return {
...state,
open: action.payload
};
default:
return state;
}
}
My combined reducer:
import ContentReducer from './ContentReducer';
const rootReducer = combineReducers({
content: ContentReducer
});
And where I'm initializing my store:
import rootReducer from './Reducers';
const store = createStore(rootReducer);
I tried setting up an initial state for the store like:
const initialStore = {
open: false
}
const store = createStore(rootReducer, initialStore);
But that gave me an error as well.
Upvotes: 0
Views: 317
Reputation: 85191
const mapStateToProps = (state: any) => ({
open: state.open,
})
in this function, state
is the root state. Ie, the one produced by the rootReducer. This state looks like:
{
content: {
open: // some boolean
}
}
So to access it, you need to do:
const mapStateToProps = (state: any) => ({
open: state.content.open,
})
PS, since you're using typescript, you should be able to do better than any
for the type. At the very least, you could do this:
// in the file with the root reducer:
const rootReducer = combineReducers({
content: ContentReducer
});
export type RootState = ReturnType<typeof rootReducer>;
// And then use it elsewhere like:
const mapStateToProps = (state: RootState) => ({
open: state.content.open,
})
Upvotes: 3
Reputation: 6052
mapStateToProps gets your root reducer state - so use state.content.open instead of state.open.
Upvotes: 0