Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
connect.js explained
// connect() is a function that injects Redux-related props into your component.
// You can inject data and callbacks that change that data by dispatching actions.
function connect(mapStateToProps, mapDispatchToProps) {
// It lets us inject component as the last step so people can use it as a decorator.
// Generally you don't need to worry about it.
return function (WrappedComponent) {
// It returns a component
return class extends React.Component {
render() {
return (
// that renders your component
<WrappedComponent
{/* with its props */}
{...this.props}
{/* and additional props calculated from Redux store */}
{...mapStateToProps(store.getState(), this.props)}
{...mapDispatchToProps(store.dispatch, this.props)}
/>
)
}
componentDidMount() {
// it remembers to subscribe to the store so it doesn't miss updates
this.unsubscribe = store.subscribe(this.handleChange.bind(this))
}
componentWillUnmount() {
// and unsubscribe later
this.unsubscribe()
}
handleChange() {
// and whenever the store state changes, it re-renders.
this.forceUpdate()
}
}
}
}
// This is not the real implementation but a mental model.
// It skips the question of where we get the "store" from (answer: <Provider> puts it in React context)
// and it skips any performance optimizations (real connect() makes sure we don't re-render in vain).
// The purpose of connect() is that you don't have to think about
// subscribing to the store or perf optimizations yourself, and
// instead you can specify how to get props based on Redux store state:
const ConnectedCounter = connect(
// Given Redux state, return props
state => ({
value: state.counter,
}),
// Given Redux dispatch, return callback props
dispatch => ({
onIncrement() {
dispatch({ type: 'INCREMENT' })
}
})
)(Counter)
@demukeshchouhan
Copy link

demukeshchouhan commented Dec 6, 2018

If I use this syntax.

const mapState = ({ state }) => ({ ...state });

  1. The component will be heavy?
  2. The component will be re-render every time store change?
  3. The component will take extra memory to store props?
  4. Or it's just a syntactic sugar?

@farazh
Copy link

farazh commented Jan 17, 2019

Great Explanation!

@dinukadev
Copy link

dinukadev commented Feb 21, 2019

This helped. Thank you!

@ezmiller
Copy link

ezmiller commented Mar 4, 2019

Is it accurate to say that connect implements some variant of the observer pattern? If yes or no (or kinda), why?

@kas-elvirov
Copy link

kas-elvirov commented Jan 10, 2020

@ezmiller i would say - connect() is an observer for sure. Why? Go to the internet

@cyogian
Copy link

cyogian commented Feb 20, 2020

I just came here to see how a HOC works in practical. Thanks for this explaination.

@aakash-cr7
Copy link

aakash-cr7 commented Mar 15, 2020

@gaearon don't you think the subscription logic should be in the constructor and not componentDidMount? If I am dispatching an action from WrappedComponent's componentDidMount. We won't see the updated state (it wont re render) in WrappedComponent, since componentDidMount of the WrappedComponent will run first before the subscription happens in componentDidMount inside connect()

@VitaminCtea
Copy link

VitaminCtea commented Apr 15, 2020

Very clear explanation! 👍

@gideonmensadappah
Copy link

gideonmensadappah commented Apr 16, 2020

Thank You That was a clear explanation !!

@4nkitpatel
Copy link

4nkitpatel commented Jul 13, 2020

Thanks, this mental model helping me a lot while learning react with redux :)

@prajapati-parth
Copy link

prajapati-parth commented Jul 26, 2020

@gaearon when connecting a component and using redux-thunk, dispatching twice would update the state twice. Would that mean that connected components would re-render twice (considering that the changes in state are something that would cause a re-render if used with component's native state)?

@jaiho8816
Copy link

jaiho8816 commented Nov 10, 2021

thanks @gaearon

@nguyenyou
Copy link

nguyenyou commented Nov 11, 2021

Thank you 🚀🚀🚀

@farhdibehnamdev
Copy link

farhdibehnamdev commented Jun 13, 2022

Thank you so much. It was so helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment