I'm facing a problem with mapStateToProps argument. It seems a very simple error but I'm not able to figure out what's happening. Basically, what I'm trying to do is toggle a sidebar menu with react-redux and react saga. Everything works well but I'm getting the following error:
Uncaught Error: Invalid value of type object for mapStateToProps argument when connecting component Sidebar.
Appreciate any help:
Index app/js/index.js
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import configureStore from '../store/configureStore';
import Canvas from '../components/Canvas/Canvas';
const store = configureStore();
render(
<Provider store={store}>
<Canvas />
</Provider>,
document.getElementById('app'),
);
Reducers
(Index) app/reducers/index.js
import { combineReducers } from 'redux';
import sidebar from './sidebar';
const rootReducer = combineReducers({
sidebar,
});
export default rootReducer;
(Sidebar) app/reducers/sidebar.js
import {
TOGGLE_SIDEBAR,
} from '../actions';
const sidebar = (state = { value: true }, action) => {
switch (action.type) {
case TOGGLE_SIDEBAR:
debugger;
return action.value;
default:
debugger;
return state.value;
}
}
export default sidebar;
Sagas
index.js app/sagas/index.js
import { fork } from 'redux-saga/effects';
import { watcher } from './watcher';
function* rootSaga() {
yield [
fork(watcher),
];
}
export default rootSaga;
sidebar.js app/sagas/sidebar.js
import { put } from 'redux-saga/effects';
import {
TOGGLE_SIDEBAR,
} from '../actions';
export function* sidebar () {
try {
yield put ({ type: TOGGLE_SIDEBAR });
} catch (err) {
debugger;
}
}
watcher.js app/sagas/watcher.js
import { takeEvery } from 'redux-saga/effects';
import { sidebar } from './sidebar';
import {
TOGGLE_SIDEBAR,
} from '../actions';
export function* watcher() {
try {
yield takeEvery(TOGGLE_SIDEBAR, sidebar);
} catch (err) { debugger; }
}
Actions app/actions/index.js
export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR';
export const toggleSidebar = (value) => ({
type: TOGGLE_SIDEBAR,
value,
});
Containers SidebarContainer.js app/containers/sidebarContainer.js
import { connect } from 'react-redux';
import {
toggleSidebar as callToggleSidebar,
} from '../actions';
import Sidebar from '../components/Sidebar/Sidebar';
debugger;
const mapStateToProps = (state) => {
debugger;
return {
open: state.sidebar,
}
};
const mapDispatchToProps = dispatch => ({
toggleSidebar: (val) => { dispatch(callToggleSidebar(val)); },
});
export default connect({
mapStateToProps,
mapDispatchToProps,
})(Sidebar);
Components
Sidebar.jsx app/components/Sidebar.jsx
import React from 'react';
import { PropTypes } from 'prop-types';
import './styles/styles.less';
const Sidebar = ({ open, toggleSidebar }) => (
<div className={open ? 'sidebar sidebar-open' : 'sidebar sidebar-closed'}>
<div className='show-hide-container'>
<button onClick={() => toggleSidebar(!open)}>
<i className="fa fa-arrow-right" aria-hidden="true" />
</button>
</div>
Sidebar
</div>
);
Sidebar.propTypes = {
open: PropTypes.bool.isRequired,
toggleSidebar: PropTypes.func.isRequired,
};
export default Sidebar;
As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.
The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.
The mapStateToProps(state, ownProps) is specified as the first argument of connect() call and its ownProps parameter receives the props object of the wrapper component. If the ownProps parameter is not present, React Redux skips calling the function at the props change.
mapStateToProps Definition The React Redux’s mapStateToProps has 2 parameters. The first is the state and the second is an optional ownProps parameter. It returns a plain object containing the data that the connected component needs.
The arguments [1] is undefined since we didn’t include the ownProps parameter. We can define mapStateToProps and use it to get the latest state from our Redux Store to our React app via the connect function. It has 2 parameters, which are state for the store’s state and ownProps for the props that we pass into the component ourselves.
It’s frequently referred to as just mapState for short. It is called every time the store state changes. It receives the entire store state, and should return an object of data this component needs.
Much like a Redux reducer, a mapStateToProps function should always be 100% pure and synchronous. It should only take state (and ownProps) as arguments, and return the data the component needs as props without mutating those arguments.
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Sidebar);
Please try, passing mapStateToProps
and mapDispatchToProps
as arguments instead of an object.
connect
is a function expecting state and dispatch functions.
https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With