Understanding the Very Basics of the React-Redux Connect Function

It’s a function that takes two functions and returns a function that returns a wrapped component. Get it? Hint: It’s not magic.

The React-Redux connect function does exactly what its name implies, it connects a component to your Redux store, allowing you to subscribe to changes in the store state, and to dispatch actions to the store.

The first thing to note about the connect function is how it has access to our store in the first place. We could pass the store as prop to each individual connected component, but we have the Provider function to do that for us. To use it, just add something like this to the root of our app:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './store'
import { Provider } from 'react-redux'

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

Now that we have our store passed down, we’re ready to use the connect function itself. The connect function accepts two functions as its main arguments, often called mapStateToProps and mapDispatchToProps respectively.

mapStateToProps takes in the state from the store as its first argument, making these props available to your wrapped component, and subscribing to any changes to these props in your Redux store. It must return an object where the keys are the names of the props you want passed down from your store state to your wrapped component.

const mapStateToProps = state => {
return {
todosList: state.todosList
}
}

mapDispatchToProps is the second argument passed to connect, and it allows us to dispatch actions (especially thunks) to our redux store. This function receives the dispatch method as an argument, and also returns an object of callback props to be passed down to our wrapped component.

const mapDispatchToProps = dispatch => {
return {
addToTodosList: (todo) => dispatch(addToTodosList(todo))
}
}

So, when we pass these two functions to the React-Redux connect function, we are returned a function that when invoked returns a new React component that renders our component with all those state and dispatch props attached to it. Whew. We can immediately invoke this function, passing in the component we want to wrap (or connect). Here is a very basic example of my understanding of this:

connect(mapStateToProps, mapDispatchToProps)(TodosList)
//returns to us (with a bunch of other functionality excluded for brevity):
class ConnectedComponent extends React.Component {
render() {
<componentToWrap
todosList = {this.props.todosList}
addToTodosList = {this.props.addToTodosList}
/>
}
}

And voila! We now have a connected component that is subscribed to changes in our Redux store state, and can also dispatch actions to our Redux store! Isn’t that grand?

Side note: I also love the React-Redux function because it is a great real-life example of functional programming concepts like currying and closure that were difficult for me to grasp when first learning to code.

Check out this awesome gist by Dan Abramov for his mental model of even more things that are happening under the hood of this function: https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e

Happy connecting!