在 React 中,PureComponent 是一种组件类型,它可以优化 React 应用的性能,它会自动对组件的 props 和 state 做浅层比较,如果发现没有变化则不会重新渲染组件,这可以大大减少应用的渲染次数。但对于一些无状态的函数组件,我们并不能使用 PureComponent 来进行性能优化,此时就需要用到 React 的另外一种优化方式 -- PureRenderMixin。
PureRenderMixin 是一个混入(mixin)类,可以被其他组件继承或者使用。当使用 mixin 时,会将 mixin 的所有属性和方法添加到现有组件中。在 React-addons 中,已经包含了 PureRenderMixin 这个混入类,但是自从 React 15.x 版本开始,官方停用了 React-addons,因此,我们需要使用 standalone-react-addons-pure-render-mixin 这个 npm 包来实现 PureRenderMixin 的功能。
安装
首先我们需要安装 standalone-react-addons-pure-render-mixin:
--- ------- ----------------------------------------- ------
基本用法
使用 PureRenderMixin 的方法非常简单,只需要在组件中引入 PureRenderMixin 并将其混入组件中即可,如下所示:
------ ----- ---- -------- ------ --------------- ---- -------------------------------------------- ----- ----------- ------- --------------- - ------------------ - ------------- -------------------------- - ------------------------------------------------- - -------- - ------ ---------- ------------- - -
上面的代码中,我们首先引入 PureRenderMixin,然后在组件的 constructor 中调用 PureRenderMixin 的 shouldComponentUpdate 方法,并将其绑定到当前组件的实例中。然后在组件的 render 方法中返回一个简单的 "Hello World!" 字符串。这里我们通过继承 React.Component 的方式来定义组件,如果您使用的是 React.createClass 来创建组件,那么您可以直接使用 mixin 的方式来混入 PureRenderMixin,具体如下所示:
------ ----- ---- -------- ------ --------------- ---- -------------------------------------------- ----- ----------- - ------------------- ------- ------------------ -------- - ------ ---------- ------------- - ---
深入学习
使用 PureRenderMixin 可以帮助我们优化 React 应用的性能,但是在实际开发中我们还需要注意一些细节。下面我们来深入了解 PureRenderMixin 的一些特性和注意事项。
shouldComponentUpdate 方法
PureRenderMixin 的核心机制是 shouldComponentUpdate 方法,用于告诉 React 是否需要重新渲染组件。默认情况下,React 会在父组件重新渲染时,就会调用子组件的 render 方法,然后比较新旧组件的 props 和 state,如果有不同就会重新渲染组件,否则就不会更新。但在一些场景中,我们可能需要手动控制更新流程。此时,我们可以定义自己的 shouldComponentUpdate 方法,通过比较新旧 props 和 state,来告诉 React 是否需要重新渲染组件。
对于 PureComponent,其默认的 shouldComponentUpdate 方法已经实现了上述逻辑,所以不需要手动定义 shouldComponentUpdate 方法。而对于没有继承自 PureComponent 的组件,我们可以手动实现 shouldComponentUpdate 方法,或者使用 PureRenderMixin 来实现。
----- ----------- ------- --------------- - ------------------ - ------------- -------------------------- - ------------------------------------------------- - -------- - ------ ----------------------------- - -
上面的代码中,我们定义了一个简单的组件 MyComponent,并使用 PureRenderMixin 来实现 shouldComponentUpdate 方法。在该方法中,我们比较了新旧 props 的 name 属性,如果相同则返回 false,表示不需要重新渲染组件;否则返回 true,需要重新渲染组件。
混入的顺序
在使用 mixin 时,如果多个 mixin 混入了同一个组件,那么它们的顺序将影响到方法调用的结果。在 React 中,方法的调用顺序是从右到左。即先调用第一个 mixin 的相应方法,然后再调用第二个 mixin 的相应方法,以此类推。最后,在调用组件自身的相应方法。
将 PureRenderMixin 和其他 mixin 混入同一个组件时,需要注意 mixin 的顺序。例如:
----- ----------- ------- --------------- - ------------------ - ------------- -------------------------- - ------------------------------------------------- - -------- - ------ ----------------------------- - - ----- ------------ - - -------------------------------- ---------- - ------ ----- - - ----- -------------- - --------------------------
上面的代码中,我们定义了两个 mixin,并将它们混入同一个组件 FinalComponent 中。由于 AnotherMixin 的 shouldComponentUpdate 方法返回 true,所以 FinalComponent 的 shouldComponentUpdate 方法将始终返回 true,也就是说,该组件会重新渲染每一次组件的 props 或 state 发生变化时。
但是,如果我们将 AnotherMixin 放到 PureRenderMixin 的前面,则会有不同的结果:
----- -------------- - -------------------------------------------
上面的代码中,我们先将 AnotherMixin 混入 MyComponent 中,然后再通过 PureRenderMixin 混入到 FinalComponent 中。由于 PureRenderMixin 的 shouldComponentUpdate 方法会比 AnotherMixin 先调用,所以其结果会覆盖 AnotherMixin 的结果。因此,FinalComponent 的 shouldComponentUpdate 方法将返回 false,除非其 props 或 state 发生了变化。
避免使用箭头函数
在使用 PureRenderMixin 时,需要注意避免在组件内部定义箭头函数,因为箭头函数的 this 绑定是由上下文决定的,不受组件实例的控制。因此,如果我们在组件内定义箭头函数,可能会导致 PureRenderMixin 失效,从而引发不必要的组件重新渲染。
----- ----------- ------- --------------- - ------------------ - ------------- -------------------------- - ------------------------------------------------- - ----------- - -- -- - -- -- --------- - -------- - ------ ------- -------------------------------- ------------- - -
上面的代码中,我们在组件内部定义了一个 handleClick 箭头函数,并将其作为事件处理函数。由于 handleClick 是箭头函数,因此其 this 绑定不受 MyComponent 实例的控制,可能会影响 PureRenderMixin 的比较结果。为了避免这种情况,我们应该使用普通函数来定义事件处理函数。
----- ----------- ------- --------------- - ------------------ - ------------- -------------------------- - ------------------------------------------------- - ------------- - -- -- --------- - -------- - ------ ------- ------------------------------------------- ------------- - -
上面的代码中,我们将 handleClick 定义为普通方法,然后在 JSX 中通过 bind 绑定 this。这样,PureRenderMixin 就可以正确比较新旧 props 和 state,以决定是否需要重新渲染组件。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/5eedcb90b5cbfe1ea0612625