文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
不可变数据和纯粹渲染
我们之前已经讨论了许多关于不可变数据的红利,但是,当它和 react 结合时还会有一个非常屌的好处:
如果我们创建纯 react 组件并传递给它不可变数据作为属性参数,我们将会让 react 在组件渲染检测中得到最大性能。
这是靠 react 提供的 PureRenderMixin 实现的。
当该 mixin 添加到组件中后,组件的更新检查逻辑将会被改变,由深比对改为高性能的浅比对。
我们之所以可以使用浅比对,就是因为我们使用的是不可变数据。如果一个组件的所有参数都是不可变数据,
那么将大大提高应用性能。
我们可以在单元测试里更清楚的看见差别,如果我们向纯组件中传入可变数组,当数组内部元素产生改变后,组件并不会
重新渲染:
//test/components/Voting_spec.jsx
it('renders as a pure component', () => {
const pair = ['Trainspotting', '28 Days Later'];
const component = renderIntoDocument(
<Voting pair={pair} />
);
let firstButton = scryRenderedDOMComponentsWithTag(component, 'button')[0];
expect(firstButton.getDOMNode().textContent).to.equal('Trainspotting');
pair[0] = 'Sunshine';
component.setProps({pair: pair});
firstButton = scryRenderedDOMComponentsWithTag(component, 'button')[0];
expect(firstButton.getDOMNode().textContent).to.equal('Trainspotting');
});
如果我们使用不可变数据,则完全没有问题:
//test/components/Voting_spec.jsx
import React from 'react/addons';
import {List} from 'immutable';
import Voting from '../../src/components/Voting';
import {expect} from 'chai';
const {renderIntoDocument, scryRenderedDOMComponentsWithTag, Simulate}
= React.addons.TestUtils;
describe('Voting', () => {
// ...
it('does update DOM when prop changes', () => {
const pair = List.of('Trainspotting', '28 Days Later');
const component = renderIntoDocument(
<Voting pair={pair} />
);
let firstButton = scryRenderedDOMComponentsWithTag(component, 'button')[0];
expect(firstButton.getDOMNode().textContent).to.equal('Trainspotting');
const newPair = pair.set(0, 'Sunshine');
component.setProps({pair: newPair});
firstButton = scryRenderedDOMComponentsWithTag(component, 'button')[0];
expect(firstButton.getDOMNode().textContent).to.equal('Sunshine');
});
});
如果你跑上面的两个测试,你将会看到非预期的结果:因为实际上 UI 在两种场景下都更新了。那是因为现在组件
依然使用的是深比对,这正是我们使用不可变数据想极力避免的。
下面我们在组件中引入 mixin,你就会拿到期望的结果了:
//src/components/Voting.jsx
import React from 'react/addons';
import Winner from './Winner';
import Vote from './Vote';
export default React.createClass({
mixins: [React.addons.PureRenderMixin],
// ...
});
//src/components/Vote.jsx
import React from 'react/addons';
export default React.createClass({
mixins: [React.addons.PureRenderMixin],
// ...
});
//src/components/Winner.jsx
import React from 'react/addons';
export default React.createClass({
mixins: [React.addons.PureRenderMixin],
// ...
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论