New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do I need connect() from React Redux or should I use store.subscribe()? #281

Closed
TomiS opened this Issue Feb 5, 2016 · 2 comments

Comments

2 participants
@TomiS

TomiS commented Feb 5, 2016

Greetings to all of you seasoned Redux veterans!

I'm new to React and Redux but I'd like to get this stuff right before moving on with our project. I've read about connecting presentational and container components but before going there, I'd like to make a simple component that does it all. I have a Header component that should render user's username if user is authenticated. I already managed to successfully login the user using our API and update my immutable Redux store accordingly. So, looking from the surface, the following code works.

The question is whether the following implementation is an antipattern or otherwise 'bad' e.g. performance-wise? Am I allowed to call setState() manually when using Redux? Without the setState() call the component doesn't seem to recognise state changes in store at all. Is there performance (or some other relevant) differences between this implementation strategy and the one that uses mapStateToProps() method with connect()?

// import stuff...
class Header extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      isAuthenticated: false,
      username: ''
    }
    let unsubscribe = context.store.subscribe(() => {
      let state = context.store.getState();
      //state is an Immutable.Map
      let user = state.get('login').get('user');
      let newState = {isAuthenticated: state.get('login').get('isAuthenticated')};
      if (newState.isAuthenticated) {
        newState.username = user.get('username');
      }
      this.setState(newState);
    });
  }

  render() {
    let loginStatus = null;
    if (this.state.isAuthenticated) {
      loginStatus = (
        <p>Logged in as ({this.state.username})</p>
      );
    }
    return (
      <div id="login-status">
        {loginStatus}
      </div>
    );
  }
}
Header.contextTypes = {
  store: React.PropTypes.object
}
export default Header

@TomiS TomiS changed the title from Updating React component state from immutable Redux store to Updating React Component State from Immutable Redux Store Feb 5, 2016

@gaearon

This comment has been minimized.

Contributor

gaearon commented Feb 5, 2016

This is a good example to understand how React Redux works, but I wouldn’t do this in a real app.

Without the setState() call the component doesn't seem to recognise state changes in store at all

Yes, this is precisely how React works: you must tell it that the state has updated.

The question is whether the following implementation is an antipattern or otherwise 'bad' e.g. performance-wise?

One issue you have there is that you never unsubscribe. You should be unsubscribing in componentWillUnmount.

Is there performance (or some other relevant) differences between this implementation strategy and the one that uses mapStateToProps() method with connect()?

Yes. You don't implement any optimizations. For example, components generated by connect() bail out of rendering if they see that the props returned from mapStateToProps() are shallowly equal to their previous versions.

Have a look at connect() source code. You will see that the idea is the same, but it has a ton of optimizations at different points. In general, it avoids calling your functions or rendering unless absolutely necessary.

I was a guest at this readthesource episode explaining how React Redux works so you might want to check it out.

We definitely recommend using React Redux for best performance instead of rolling your own subscription logic.

@gaearon gaearon closed this Feb 5, 2016

@gaearon gaearon changed the title from Updating React Component State from Immutable Redux Store to Do I need connect() from React Redux or should I use store.subscribe()? Feb 5, 2016

@TomiS

This comment has been minimized.

TomiS commented Feb 5, 2016

Thanks @gaearon. This was extremely helpful. Have a nice weekend.

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