Sorry but all the explanations this far have been bad so I thought I’d simplify it.
In plain Redux without connect you need to manually bind up your store.dispatch to your components as well as subscribe to updates so you can call store.getState(). But your components are suppose to be dumb.
const store = createStore(reducer);
const render = () => ReactDOM.render( // turns ReactDOM.render into executable function
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>,
document.getElementById('root')
);
render();
store.subscribe(render);
So rather than manually linking dispatch and subscribing to updates we create two mapping functions, both of which bind the dispatch and the state to props of the ‘connected component’. So in this case all updates to this.store.getState().value are mapped to this.props.value and rather than mapping dispatch directly, we just wrap it and pass it in as a prop.
// create component
class ContainerComponent extends React.Component {
render() {
<PresentationComponent
value={this.props.value}
onIncrement={this.props.onIncrement}
onDecrement={this.props.onDecrement} />
}
}
// create state mapping
function mapStateToProps(state) {
return {
value: state.value
};
}
// add dispatch mapper
function mapDispatchToProps(dispatch) {
return {
onIncrement: function() {
dispatch({type:'INCREMENT'});
},
onDecrement : function() {
dispatch({type:'DECREMENT'});
}
};
}
export default connect(mapStateToProps,mapDispatchToProps)(ContainerComponent);
Now when you call your components you can simply call the value passed in like so.
export default class PresentationComponent extends React.Component {
render() {
return (
<div>
<span>{this.props.value}</span>
<button onClick={this.props.onIncrement}>Increment</button>
<button onClick={this.props.onDecrement}>Decrement</button>
</div>
);
}
}
For more information you can checkout both of these github projects for reference.