Why redux suggests to only connect to top level components?

后端 未结 5 410
悲哀的现实
悲哀的现实 2020-12-25 12:53

I\'m new to redux and react-redux, in the mean time I am trying to make a redux app.

I don\'t understand the statement on redux document:

Then

相关标签:
5条回答
  • 2020-12-25 13:21

    The answer is in this section from your excerpt of the docs:

    While technically you can connect() any component in your app to Redux store, avoid doing this too deeply, because it will make the data flow harder to trace.

    One of the core principles of Redux is data should generally flow from the top down, i.e. it should be unidirectional. If you connect too many lower level components, your data flow is no longer unidirectional. The main consequence of this is that it is much easier to have inconsistent state among your components.

    When going top-down, which is what naturally happens when you only connect a limited number of high level components, it is much harder to create situations where you have inconsistent state, hence the advice in the docs.

    0 讨论(0)
  • 2020-12-25 13:23

    When I had one container at the top, I had efficiency problems because React rerendered all my components during slightest update somewhere in the tree. So I abandoned that approach and made my app against docs, which turned out to be faster.

    But later I've seen that even Redux author wrote on his Twitter:

    Emphasizing “one container component at the top” in Redux examples was a mistake. Don’t take this as a maxim.

    https://twitter.com/dan_abramov/status/668585589609005056

    and

    Try to keep your presentation components separate. Create container components by connecting them when it’s convenient. https://twitter.com/dan_abramov/status/668586001175048192

    0 讨论(0)
  • 2020-12-25 13:30

    In some cases, you can use connect()ed components deeper down. I wouldn't interpret the documentation so strictly.

    Generally speaking, if you find yourself passing down too many props from your components and the components doing the passing aren't using those props, then they can be moved to a separate container component.

    If you find yourself constantly writing props down a component chain it might be time to add a container:

    // A blog post view component
    render () {
      const {post} = this.props;
    
      return (
        <div>
          <h1>{post.title}</h1>
    
          <Author author={this.props.author}
            onClick={this.props.favAuthor}
            onHover={this.props.authorDetails}
            isAuthorFaved={this.props.isAuthorFaved}
            isAuthorFollowed={this.props.isAuthorFollowed}/>
        </div>
      )
    }
    

    In this case, the post component doesn't have any use or need of any props used for <Author/>. You might want to consider making an <AuthorContainer author={this.props.author}/> instead. The author belongs to the post, so you will need that bit of information. The rest can be computed using state in the container's mapStateToProps(state, ownProps) function where ownProps.author is the author object.

    Again, this is a contrived example, but it is really up to you in the end where the logic belongs.

    0 讨论(0)
  • 2020-12-25 13:42

    Reading the latest answers as of when I post my answer here, I'd like to further add to the consensus of having each component connected using the official Redux style guide:

    Prefer having more UI components subscribed to the Redux store and reading data at a more granular level. This typically leads to better UI performance, as fewer components will need to render when a given piece of state changes.

    For example, rather than just connecting a <UserList> component and reading the entire array of users, have <UserList> retrieve a list of all user IDs, render list items as <UserListItem userId={userId}>, and have <UserListItem> be connected and extract its own user entry from the store.

    This applies for both the React-Redux connect() API and the useSelector() hook.

    0 讨论(0)
  • 2020-12-25 13:46

    As mentioned, Abramov (Redux author) has walked-back his advice re: connect()ed components. He articulates a nice rule of thumb in this Reddit post on the topic:

    I do it this way:

    1. Start by using one container and several presentational components

    2. As presentational component tree grows, “middle” components start to pass too many props down

    3. At this point, I wrap some leaf components into containers so that “middle” components don’t need to accept and pass down props that are completely unrelated to them

    4. Repeat

    If you watch the last ten videos from my course on Egghead, this is exactly the approach I demonstrate: https://egghead.io/series/getting-started-with-redux

    From my reading, the initial advice on connect() had nothing to do w/ performance and everything to do with modular components & ease-of-reasoning about data flow in larger apps.

    In fact, more connect()ed components might be a performance advantage vs. the 1-container-to-rule-them-all top-heavy pattern. Abramov once more:

    Both approaches are fine, and having nested connect() components is actually going to give you more performance. The downside is they're slightly more coupled to the application and slightly harder to test, but that may not be a big issue.

    0 讨论(0)
提交回复
热议问题