We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
花了一天时间,看了很多文章,大体上是理解了react的render机制,以及不可变数据在render机制中起到的作用。
安装一个工具可以检测组件是否发生了不必要的渲染。如果发生了不必要的组件渲染,控制台会精确定位并且打印出那些状态触发了不必要的渲染。然后针对性的进行优化,简直是神器啊。
npm i -D why-did-you-update
在index.js加
if (process.env.NOED_ENV !== 'production') { const { whyDidYouUpdate } = require('why-did-you-update'); whyDidYouUpdate(React); }
class App extends component { constructor(props) { super(props); this.state = { count: 0, user: { name: 'zp' } } } handleClick = () => { this.setState({ count: 0 }); } render() { return ( <div> <div onClick={this.handleClick}>点击我</div> <div>{this.state.count}</div> </div> ); } }
保存文件,打开页面,点击点击我,会发现控制台打印出了一个console,提示这个render是不必要的render,count并没有改变,但是组件却重新渲染了。
PureComponent是react自带的继承了component的类,但是在组件re-render的时候加了一层判断,浅比较新的状态和旧的状态是否一致,如果新旧状态的引用不一致,则比较第一层状态值是否改变,上面的例子中count为第一层,值没有改变,所以不重新渲染。
class App extends PureComponent { // ...代码 }
为什么说是浅比较,那是因为假设我现在改更新的是user里面的name属性,name我们看看即便加了purecomponent,是否还会发生不必要的渲染呢。
修改handleClick
handleClick = () => { this.setState({ user: { name: 'zp' } }); }
此时页面console,依然打印出不必要渲染,告知这里的不必要渲染造成的原因是user的引用改变了。
由于purecomponent只比较第一层,所以第二层的user下面的值{name: 'zp'}是个引用。引用改变了,值就不一样了,就会触发re-render。相当于
deepEquals = (obj1, obj2) => { if (obj1 === obj2) { return true; } for (const key of Object.keys(obj2)) { if (obj1.hasOwnProperty(key) && obj1[key] === obj2[key]) { return true; } } return false; } shouldComponentUpdate = (nextProps, nextState) => { return !this.deepEquals(this.state, nextState) || !this.deepEquals(this.props, nextProps); }
手写shouldComponentUpdate和加purecomponent的效果是一样的,只能浅比较。
所以purecomponent解决了浅层次的dom渲染优化,但是对于结构更加复杂的嵌套的数据结构,还是会发生不必要的渲染。
网上很火的数据结构immutable.js,似乎很好的解决了这个问题,让我们看看如何简单的使用immutable.js改造上面的例子
首先本地安装immutable.js。
npm i --save immutable
这里我们先把state改造一下,使用immutable的API改造handleClick,最后render里面的dom渲染再使用API改造一下
this.state = { data: Immutable.fromJS({ count: 0, user: { name: 'zp' } }) } handleClick = () => { this.setState((d) => { return { data: d.data.updateIn(['user', 'name'], () => 'zp') // 这里改变了user里面的name,深层改变 } }) } render() { const data = this.state.data; return ( <div> <div onClick={this.handleClick}>点击我</div> <div>{data.get('count')}</div> <div>{data.getIn(['user', 'name'])}</div> </div> ); }
保存刷新页面,点击,会发现并没有多余的render。cool!
我觉得这样看来,immutable.js真的很强大很诱人,看到没有浪费的render,这让有强迫症的开发人员感到很舒服,但是网上看到immutable.js的弊端也有些,
如果不用ImmutableJS ,那么就要尽量避免使用复杂的结构,最好扁平化数据结构,但是。。。。那是不可能的!!所以,你们看着办吧。
我只想说,虽然我现在的项目并没有使用react,甚至我也没用过ImmutableJS ,但是我对react的爱是不变的,我会保持学习,一直进步。。。。嘿,小哥,招前端吗?
The text was updated successfully, but these errors were encountered:
No branches or pull requests
React渲染
花了一天时间,看了很多文章,大体上是理解了react的render机制,以及不可变数据在render机制中起到的作用。
工具
安装一个工具可以检测组件是否发生了不必要的渲染。如果发生了不必要的组件渲染,控制台会精确定位并且打印出那些状态触发了不必要的渲染。然后针对性的进行优化,简直是神器啊。
在index.js加
正常渲染
保存文件,打开页面,点击点击我,会发现控制台打印出了一个console,提示这个render是不必要的render,count并没有改变,但是组件却重新渲染了。
使用PureComponent
PureComponent是react自带的继承了component的类,但是在组件re-render的时候加了一层判断,浅比较新的状态和旧的状态是否一致,如果新旧状态的引用不一致,则比较第一层状态值是否改变,上面的例子中count为第一层,值没有改变,所以不重新渲染。
为什么说是浅比较,那是因为假设我现在改更新的是user里面的name属性,name我们看看即便加了purecomponent,是否还会发生不必要的渲染呢。
修改handleClick
此时页面console,依然打印出不必要渲染,告知这里的不必要渲染造成的原因是user的引用改变了。
由于purecomponent只比较第一层,所以第二层的user下面的值{name: 'zp'}是个引用。引用改变了,值就不一样了,就会触发re-render。相当于
手写shouldComponentUpdate和加purecomponent的效果是一样的,只能浅比较。
所以purecomponent解决了浅层次的dom渲染优化,但是对于结构更加复杂的嵌套的数据结构,还是会发生不必要的渲染。
immutable.js
网上很火的数据结构immutable.js,似乎很好的解决了这个问题,让我们看看如何简单的使用immutable.js改造上面的例子
首先本地安装immutable.js。
这里我们先把state改造一下,使用immutable的API改造handleClick,最后render里面的dom渲染再使用API改造一下
保存刷新页面,点击,会发现并没有多余的render。cool!
用不用
我觉得这样看来,immutable.js真的很强大很诱人,看到没有浪费的render,这让有强迫症的开发人员感到很舒服,但是网上看到immutable.js的弊端也有些,
如果不用ImmutableJS ,那么就要尽量避免使用复杂的结构,最好扁平化数据结构,但是。。。。那是不可能的!!所以,你们看着办吧。
我只想说,虽然我现在的项目并没有使用react,甚至我也没用过ImmutableJS ,但是我对react的爱是不变的,我会保持学习,一直进步。。。。嘿,小哥,招前端吗?
The text was updated successfully, but these errors were encountered: