首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Redux mapStateToProps多次调用

Redux mapStateToProps多次调用
EN

Stack Overflow用户
提问于 2017-04-04 09:41:02
回答 3查看 7K关注 0票数 6

我有一个非常简单的组件,它连接到redux状态并返回{fruit, vegetables}。一切都很好,但是假设我在组件中有一个图形,如果我只从API接收到更新的vegetable,则每次都要重新创建图形。

这是我的组成部分:

代码语言:javascript
复制
const Products = ({ fruit, vegetable }) =>
  <div className='Products'>
      <div>{vegetable.map(....logic here)}</div>
      <div>{Math.random()}</div> // this is to illustrate the component is rendering every time
      <Graph>Here will be a chart or a graph with fruit</Graph> //but it gets re-rendered even though there is no new fruit
  </div>

const mapStateToProps = (state) => {
  return {
    fruit: state.data.fruit,
    vegetable:  state.data.vegetable,
  }
}

export default connect(mapStateToProps)(Products)

在我看来,每一次,无论哪种状态被更新,它都会重新呈现整个组件。

有什么办法可以防止这种情况吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-04-04 09:52:41

当呈现一个React组件时,它下面的整个组件树也会被呈现--除了shouldComponentUpdate钩子返回false的组件之外。因此,在您的示例中,如果Products组件被呈现出来,那么Graph组件也是正常的。

你在这里有两个选择:

  • 如果Products组件不使用Graph组件外部的fruit支柱,则可以将图形组件直接连接到fruit状态,并使用connect函数的pure选项来避免fruit不更改时重新呈现
  • 您可以在您的shouldComponentUpdate组件中定义Graph钩子,以手动跳过不必要的呈现,或者使用帮助程序库为您执行此操作,例如recompose库的pure助手。

第一个选择是优化redux应用程序/避免不必要的呈现(通常是启动):将组件连接到最底层的有意义的存储。第二个选择是更多的逃生舱口--但仍然很有用。

正如您提到的,您使用的是无状态组件,您可以使用高阶组件从shouldComponentUpdate钩子中获益。为了理解它是如何工作的,下面是它的简单实现可以如下所示:

代码语言:javascript
复制
function pure(BaseComponent, shouldUpdateFn) {
    return class extends Component {
        shouldComponentUpdate(nextProps) {
            return shouldUpdateFn(this.props, nextProps);
        }
        render() {
            return <BaseComponent { ...this.props } />;
        }
    }
}

这将为您提供一个临时的pure,您可以在应用程序上重用它以避免不必要的呈现:它的工作方式是将您的无状态组件封装到一个新组件中,并使用所需的钩子。您可以这样使用它,例如:

代码语言:javascript
复制
export default pure(Graph, (props, nextProps) => props.fruit !== nextProps.fruit)

尽管如此,我仍然强烈鼓励您查看一下重组,它具有更细粒度的实现,并且将避免您重新发明轮子。

票数 7
EN

Stack Overflow用户

发布于 2017-04-04 09:48:00

若要防止组件在接收新道具时重登,可以在shouldcomponentupdate()中实现Graph

如果一个组件的输出不受当前状态或道具变化的影响,可以使用shouldComponentUpdate()来让它做出反应。默认行为是在每个状态更改上重新呈现,在绝大多数情况下,您应该依赖于默认行为。 当接收到新的道具或状态时,在呈现之前调用shouldComponentUpdate()。默认为true。对于初始呈现或使用forceUpdate()时,不调用此方法。 返回false并不会阻止子组件在状态更改时重新呈现。 目前,如果shouldComponentUpdate()返回false,则不会调用componentWillUpdate()、render()和componentDidUpdate()。请注意,在将来,React可能会将shouldComponentUpdate()看作是一个提示而不是一个严格的指令,返回false可能仍然会导致组件的重新呈现。 如果在分析后确定某个特定组件是缓慢的,则可以将其更改为从React.PureComponent继承,后者使用浅支柱和状态比较实现shouldComponentUpdate()。如果您确信要手工编写它,可以将this.props与nextProps进行比较,将this.state与nextState进行比较,并返回false以告诉React可以跳过更新。

要帮助您实现shouldComponentUpdate(),可以使用React shallow-compare()或自定义浅比较函数。

票数 2
EN

Stack Overflow用户

发布于 2017-04-04 12:27:24

考虑到你目前的代码。当状态发生变化时,React将更新整个组件。因此,图形组件将得到更新。

如果不希望图形组件得到更新,可以在图形组件中添加shouldComponentUpdate,并在其中引入检查以重新呈现,如下所示

代码语言:javascript
复制
shouldComponentUpdate: function(nextProps, nextState) {
    // You can access `this.props` and `this.state` here
    // and check them against nextProps and nextState respectively.
    // return boolean(false) if you don't want the component to re-render.
  }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43203572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档