使用 Reselect
在React-Redux的 connect(mapState)中使用Reselect, 这能避免频繁的重新渲染的发生.
坏实践
let App = ({otherData, resolution}) => (
<div>
<DataContainer data={otherData}/>
<ResolutionContainer resolution={resolution}/>
</div>
);
const doubleRes = (size) => ({
width: size.width * 2,
height: size.height * 2
});
App = connect(state => {
return {
otherData: state.otherData,
resolution: doubleRes(state.resolution)
}
})(App);
在上面的代码中, 一旦otherData发生修改, 那么DataContainer和ResolutionContainer两者都会发生重新渲染, 即使在resolution的state并没有发生改变时也是这样.
这是因为doubleRes这个函数总是会返回一个新的resolutiond对象的实体.
如果doubleRes函数通过Reselect方式编写就没有这个问题了.
Reslect会记录下上一次函数调用的结果并且当再次以相同方式调用时返回相同的结果(而不是创建一个一模一样的新结果). 只有当传入的参数不同时, 才会产生新的结果.
好实践
import { createSelector } from 'reselect';
const doubleRes = createSelector(
r => r.width,
r => r.height,
(width, height) => ({
width: width * 2,
height: height * 2
})
);
参考资料:
- @esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#.cz2ypc2ob">React
- Computing Derived Data: Docs