Skip to content

Instantly share code, notes, and snippets.

@variousauthors
Last active January 26, 2019 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save variousauthors/64a1f4451c03b55b21c7c6b8bb39005c to your computer and use it in GitHub Desktop.
Save variousauthors/64a1f4451c03b55b21c7c6b8bb39005c to your computer and use it in GitHub Desktop.
If I'm being honest I must admit: it looks like the sun goes around the earth.

I've been using ReactRedux for a while and something that I've gotten used to is this.

class Parent extends React.PureComponent {
  render () {
    return <Child />
  }
}

class Child exends React.PureComponent {
  render () {
    return (
      <div>
        <p>This render function will only ever be called 1 time.</p>
        <Counter />
      </div>
    )
  }
}

class Base extends React.PureComponent {
  render () {
    return (
      <div>
        <div>{this.props.count}</div>
        <button onClick={this.props.update}/>Click Me!</div>
      </div>
  }
}

const Counter = connect(
  state => ({ count: state.count }),
  dispatch => ({ update: () => dispatch(incrementCount()))
)

Even though those components are all marked PureComponents, the <Counter/> will re-render whenever the button is clicked. The <Child /> component will never re-render, even when the button is clicked. The <Counter /> component will re-render independent of its parent.

Today I learned that this is not a property of react, but rather a property of redux. My mental model was wrong.

We are using react2angular to render react components in an angular app. I decided to try using the new context API (16.3) to provide some global state that is like "configuration" from the parent app. We will still use redux for shared UI state, but the ids and some flags and callbacks that come from Angular will be provided via an AngularConsumer.

const { AngularConsumer, AngularProvider } = React.createContext({
  locale: 'en' // English is the default :/
})

class Parent extends React.PureComponent {
  render () {
    return (
      <AngularProvider value={{ locale: this.props.locale }}>
        <Child />
      </AngularProvider>
    )
  }
}

class Child extends React.PureComponent {
  render () {
    return (
      <AngularConsumer>
        {( locale ) => <Trans locale={locale}>GLOBAL.GREETINGS_HUMAN</Trans>}
      </AngularConsumer>
    )
  }
}

The parent expects props from angular. If the locale changes in the angular app, the parent will re-render (it's props have changed). It will pass the locale to the provider. The Child will not re-render and, sadly, neither will the <Trans> component nested inside. If we were using the redux store, <Trans> would re-render.

When we call connect to connect a component to the redux store, there is a call to (something like) store.subscribe() which registers a callback that let's the store directly cause the connected component to update. This is a really nice property, as it allows a deeply nested component to re-render while the parents do not.

In retrospect, I wonder what exactly I thought was going on.

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