How does redux's connect work?
ahmedgaafer
Posted on February 6, 2023
Just use it dude...
This what some of my colleagues tell me when I try to understand how the magic works.
Disclaimer:
This is an over simplification of how this function works and not the actual implementation.
But it can show you how the general Idea/Implementation works
I always wondered on how the state management libs like redux inject the props to the components that I use. Now I know and let me take you to a small code snippet to explain to you how it works.
first we have our component
MyComponent.js
import { connect } from "../redux";
import { selectA } from "./selectors";
// Let us imagine that this is a react component for simplicity
function MyComponent(props) {
console.log(props);
props.setA();
}
const mapStateToProps = (state) => {
return {
myA: selectA(state)
};
};
const mapDispatchToProps = (dispatch) => {
return {
setA: () => dispatch({ type: "SET_A", a: 1 })
};
};
const App = connect(mapStateToProps, mapDispatchToProps)(MyComponent);
// simulate react call "also let us imagine that react calls it's components in that way for simplicity"
const externalProps = {
a: 1,
b: 2
};
App(externalProps);
This is our standard react component with the mapDispatchToProps
mapStateToProps
connect
functions.
now let us take a dive into the connect.
First we have a global store that the connect have access for
const store = {
a:1
}
export const connect = () =>{
};
if we look closely to the connect we can find that it is a function that takes both mapDispatchToProps
mapStateToProps
and returns a function that we pass our component to.
let us do that
const store = {
a:1
}
export const connect = (mapstatetoprops, mapdispatchtoprops) => (component) => {
};
Now what should we do??
let us handle mapStateToProps
first.
It is simply mapping. all we have to do is pass it the current store and it will evaluate all the values according to the function.
const store = {
a:1
}
export const connect = (mapstatetoprops, mapdispatchtoprops) => (component) => {
const stateValues = mapstatetoprops(props)
};
now mapDispatchToProps
but we have to add a mock for the dispatch function for that. Let us do it.
const dispatch = (action) => {
console.log(`DISPATCH WAS CALLED WITH ACTION`, action);
};
const store = {
a:1
}
export const connect = (mapstatetoprops, mapdispatchtoprops) => (component) => {
const stateValues = mapstatetoprops(props)
};
And yes you guessed it. All we have to do now is pass the dispatch to the mapDispatchToProps
.
const dispatch = (action) => {
console.log(`DISPATCH WAS CALLED WITH ACTION`, action);
};
const store = {
a:1
}
export const connect = (mapstatetoprops, mapdispatchtoprops) => (component) => {
const stateToProps = mapstatetoprops(props);
const dispatchToProps = mapdispatchtoprops(dispatch);
};
Now that we have the evaluation of both mapDispatchToProps
& mapStateToProps
. The actual connect returns a react component with those values injected as props but as we are just using simple functions I will write the equivalent code to it
const dispatch = (action) => {
console.log(`DISPATCH WAS CALLED WITH ACTION`, action);
};
const store = {
a:1
}
export const connect = (mapstatetoprops, mapdispatchtoprops) => (component) => {
const stateToProps = mapstatetoprops(props);
const dispatchToProps = mapdispatchtoprops(dispatch);
return function () {
component.apply(this , [
{
...stateToProps ,
...dispatchToProps ,
...arguments[0] // the passed props if they exist
}
]);
};
};
Now if we open the console/ dev tools to view the logs from our function - cough couch... - component.
function MyComponent(props) {
console.log(props);
props.setA();
}
We find that all of the passed props, mapDispatchToProps
and mapStateToProps
mapped all of their values inside our function.
That is it now you know roughly how redux's connect work.
If you like this content and want me to write more of How does it work give this post a like it will tell me that you guys want more. Or write a comment telling me which topics you want me to investigate for you.
Thanks,
Ahmed S. Gaafer
Posted on February 6, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.