什麼是 Impure Component
import React, { Component } from react;nimport shallowequal from shallowequal;nnclass FullName extends Component {n shouldComponentUpdate(nextProps) {n return !shallowequal(this.props, nextProps)n }nn render() {n const { firstName, lastName } = this.props;nn return (n <div>{firstName} {lastName}</div>n )n }n}n
React 官方也提供了 PureRenderMixin (給 React.createClass 用)和 React.PureComponent 來讓我們方便地聲明一個 Pure Component。
那麼既然有 Pure Component 的說法,肯定還有相對的 Impure Component。一言以蔽之,只要你的組件依賴了 props 和 state 之外的數據,你的組件就不是 pure 的,我們來看例子。
例子一
class FullName extends Component {n render() {n const { firstName, lastName } = this.props;nn return (n <div>{firstName} {lastName} - {new Date}</div>n )n }n}n
我們在這裡增加了一個當前日期的顯示,導致即使 firstName 和 lastName 不變化,組件每次 render 的結果也是不同的,這個組件就沒辦法用 shouldCompoentUpdate 去優化了。
例子二
class App extends Component {n state = {n lastName: ,n }nn handleChange = e => {n this.setState({ lastName: e.target.value });n }nn renderLastName = () => {n return this.state.lastName;n }nn render() {n <div>n <input type="text" onChange={this.handleChange} />n <FullName firstName="Ava" lastName={this.renderLastName} />n </div>n }n}nnnclass FullName extends Component {n render() {n const { firstName, lastName } = this.props;nn return (n <div>{firstName} {lastName()}</div>n )n }n}n
這個例子我們把 lastName 變成一個方法傳進來,這樣其實 FullName 組件通過閉包,而不是通過 props,依賴了 App 的 state.lastName ,導致在 firstName 和 lastName 都不變化的情況下,FullName 會根據 state.lastName 的不同 render 出不同的結果。
例子三
class App extends Component {n static childContextTypes = {n firstName: React.PropTypes.string,n lastName: React.PropTypes.string,n }nn getChildContext() {n return {n firstName: Taylor,n lastName: Swift,n };n }nn render() {n <Segment>n <FullName />n </Segment>n }n}nnclass Segment extends Component {n render() {n <div>{this.props.children}</div>n }n}nnclass FullName extends Component {n static contextTypes = {n firstName: React.PropTypes.string,n lastName: React.PropTypes.string,n };nn render() {n const { firstName, lastName } = this.context;nn return (n <div>{firstName} {lastName}</div>n )n }n}n
這個例子其實算是 React 留給我們的一個坑(How to implement shouldComponentUpdate with this.context? · Issue #2517 · facebook/react · GitHub),這裡 FullName 是 Pure Component,但是 Segament 卻不是,因為 Segament 的 render 結果間接地依賴了上層的 context。
推薦閱讀:
※ReactNative的優質替代品 —— NativeScript 簡介
※Python同步谷歌Webfont
※【譯】如何學習V8開發
※前端與SQL
※每周一書-《Bootstrap基礎教程》