Skip to content
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
Closed

Comments

@TomiS
Copy link

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 Updating React component state from immutable Redux store Updating React Component State from Immutable Redux Store Feb 5, 2016
@gaearon
Copy link
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 as completed Feb 5, 2016
@gaearon gaearon changed the title Updating React Component State from Immutable Redux Store Do I need connect() from React Redux or should I use store.subscribe()? Feb 5, 2016
@TomiS
Copy link
Author

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants