Skip to content

Instantly share code, notes, and snippets.

@gaearon
Last active October 13, 2025 06:56
Show Gist options
  • Select an option

  • Save gaearon/1d19088790e70ac32ea636c025ba424e to your computer and use it in GitHub Desktop.

Select an option

Save gaearon/1d19088790e70ac32ea636c025ba424e to your computer and use it in GitHub Desktop.
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)
@eqyiel
Copy link
Copy Markdown

eqyiel commented Jan 6, 2017

@therewillbecode see http://redux.js.org/docs/api/Store.html#subscribe

To unsubscribe the change listener, invoke the function returned by subscribe.

@nonnontrivial
Copy link
Copy Markdown

Super clear and helpful. Thanks :)

Copy link
Copy Markdown

ghost commented Apr 22, 2017

Thank you! Pseudo-implementations help my mental model tons.

@iroy2000
Copy link
Copy Markdown

iroy2000 commented Jun 7, 2017

Thanks a lot, it makes understanding the redux implementation much easier πŸ‘

@andersonferrari
Copy link
Copy Markdown

great explanation!!! thanks!!!

@esafirm
Copy link
Copy Markdown

esafirm commented Aug 18, 2017

Wow this is great πŸ‘

@gulshanzealous
Copy link
Copy Markdown

Aha moment ! Concise and powerful : terms we hardly associate together with libraries.

@karltaylor
Copy link
Copy Markdown

πŸ‘

@dvvtms
Copy link
Copy Markdown

dvvtms commented Sep 20, 2017

here is my decorator to simplify things:

import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import * as actions from "./actions";
const decorator = ComponentToDecorate => {
  class ComponentDecorated extends React.Component {
    render() {
      const { authState, authActions, ...rest } = this.props;
      return (
        <ComponentToDecorate auth={{ state: authState, actions: authActions }}
          {...rest}
        />
      );
    }
  }

  return connect(
    state => ({
      authState: state.services.auth.authentication
    }),
    dispatch => ({
      authActions: bindActionCreators(actions, dispatch)
    })
  )(ComponentDecorated);
};

export default decorator;

i use it in some complicated components. is there is anything wrong with this?

@kinotto
Copy link
Copy Markdown

kinotto commented Oct 11, 2017

fantastic! clear and concise, thanks @gaearon

@anotherxx
Copy link
Copy Markdown

Thank you,very clear explanation,like you methods to educate.
Especially , you approach when you explain how things work under the hood!

@vitali-zaneuski
Copy link
Copy Markdown

Good and brief explanation

@Bosn
Copy link
Copy Markdown

Bosn commented May 18, 2018

Fantastic work!

@ashinzekene
Copy link
Copy Markdown

Can this be used in prod?

@sibelius
Copy link
Copy Markdown

Hooks?

@afrazahmad21
Copy link
Copy Markdown

So connect actually returns a new component hah !!! thanks for this snippet

@demukeshchouhan
Copy link
Copy Markdown

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
Copy Markdown

farazh commented Jan 17, 2019

Great Explanation!

@dinukadev
Copy link
Copy Markdown

This helped. Thank you!

@ezmiller
Copy link
Copy Markdown

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
Copy Markdown

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

@cyogian
Copy link
Copy Markdown

cyogian commented Feb 20, 2020

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

@aakashtyg
Copy link
Copy Markdown

aakashtyg 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
Copy Markdown

Very clear explanation! πŸ‘

@gideonmensadappah
Copy link
Copy Markdown

Thank You That was a clear explanation !!

@4nkitpatel
Copy link
Copy Markdown

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

@jaiho8816
Copy link
Copy Markdown

thanks @gaearon

@nguyenyou
Copy link
Copy Markdown

Thank you πŸš€πŸš€πŸš€

@farhadibehnamdev
Copy link
Copy Markdown

Thank you so much. It was so helpful.

@Brinezera
Copy link
Copy Markdown

thanks!

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