Skip to content

Commit

Permalink
feat: release PureComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
MuYunyun committed Aug 22, 2018
1 parent 98e3de5 commit 9d065a9
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 33 deletions.
34 changes: 34 additions & 0 deletions README.md
Expand Up @@ -200,6 +200,7 @@ class B extends Component {
<summary>PureComponent</summary>

```js
// 测试用例:验证 state 浅比较
class B extends PureComponent {
constructor(props) {
super(props)
Expand All @@ -226,6 +227,39 @@ class B extends PureComponent {
)
}
}

// 测试用例:验证 props 浅比较
class A extends PureComponent {
render() {
return (
<div>{this.props.count.number}</div>
)
}
}

class B extends PureComponent {
constructor(props) {
super(props)
this.state = {
count: { number: 1 }
}
}

click() {
this.setState({
count: { number: 1 }
})
}

render() {
return (
<div>
<button onClick={this.click.bind(this)}>Click Me!</button>
<A count={ this.state.count } />
</div>
)
}
}
```
</details>

Expand Down
4 changes: 2 additions & 2 deletions src/component.js
Expand Up @@ -3,8 +3,8 @@ import { renderComponent } from './render'
import { defer } from './util'

function Component(props) {
this.props = props
this.state = this.state || {}
this.props = props || {}
this.state = {}
}

// update the state of component and rerender
Expand Down
19 changes: 13 additions & 6 deletions src/pureComponent.js
Expand Up @@ -3,21 +3,28 @@ import { renderComponent } from './render'
import { defer, shallowEqual } from './util'

function PureComponent(props) {
this.props = props
this.state = this.state || {}
this.props = props || {}
this.state = {}

isShouldComponentUpdate.call(this) // 为每个 PureComponent 绑定 shouldComponentUpdate 方法
}

// update the state of component and rerender
PureComponent.prototype.setState = function(updater, cb) {
isShouldComponentUpdate.call(this) // 调用 setState 时,让 this 指向子类的实例,目的取到子类的 this.state
asyncRender(updater, this, cb)
}

function isShouldComponentUpdate() {
const cpState = this.state
this.shouldComponentUpdate = function(nextProps, nextState) {
if (!shallowEqual(cpState, nextState)) {
return true // 浅比较不等的话,渲染
const cpProps = this.props
this.shouldComponentUpdate = function (nextProps, nextState) {
if (!shallowEqual(cpState, nextState) || !shallowEqual(cpProps, nextProps)) {
return true // 只要 state 或 props 浅比较不等的话,就进行渲染
} else {
return false // 浅比较相等的话,不渲染
}
}
asyncRender(updater, this, cb)
}

// 以下代码同 component.js
Expand Down
29 changes: 4 additions & 25 deletions test/index.js
@@ -1,13 +1,9 @@
import cpreact, { Component, ReactDOM, PureComponent } from '../src/index'

class A extends PureComponent {
componentWillReceiveProps(props) {
console.log('componentWillReceivePropsA')
}

render() {
return (
<div>{this.props.count}</div>
<div>{this.props.count.number}</div>
)
}
}
Expand All @@ -16,38 +12,21 @@ class B extends PureComponent {
constructor(props) {
super(props)
this.state = {
count: 1
count: { number: 1 }
}
}

componentWillMount() {
console.log('componentWillMountB')
}

componentDidMount() {
console.log('componentDidMountB')
}

componentWillUpdate() {
console.log('componentWillUpdateB')
}

componentDidUpdate() {
console.log('componentDidUpdateB')
}

click() {
this.setState({
count: this.state.count + 1
count: { number: 1 }
})
}

render() {
console.log('renderB')
return (
<div>
<button onClick={this.click.bind(this)}>Click Me!</button>
<A count={this.state.count} />
<A count={ this.state.count } />
</div>
)
}
Expand Down

0 comments on commit 9d065a9

Please sign in to comment.