内容简介:欢迎关注我的公众号在日常开发和 Code Review 的时候,常常会发现一些共性的问题,也有很多值得提倡的做法。本文针对 React 技术栈,总结了一些最佳实践,对编写高质量的代码有一定的参考作用。
欢迎关注我的公众号 睿Talk
,获取我最新的文章:
一、前言
在日常开发和 Code Review 的时候,常常会发现一些共性的问题,也有很多值得提倡的做法。本文针对 React 技术栈,总结了一些最佳实践,对编写高质量的代码有一定的参考作用。
二、最佳实践 & 说明
- 多用 Function Component
如果组件是纯展示型的,不需要维护 state 和生命周期,则优先使用 Function Component。它有如下好处:
- 代码更简洁,一看就知道是纯展示型的,没有复杂的业务逻辑
- 更好的复用性。只要传入相同结构的 props,就能展示相同的界面,不需要考虑副作用。
- 更小的打包体积,更高的执行效率
- 多用 PureComponent
如果组件需要维护 state 或使用生命周期方法,则优先使用 PureComponent,而不是 Component。Component 的默认行为是不论 state 和 props 是否有变化,都触发 render。而 PureComponent 会先对 state 和 props 进行浅比较,不同的时候才会 render。请看下面的例子:
class Child extends React.Component { render() { console.log('render Child'); return ( <div> {this.props.obj.num} </div> ); } } class App extends React.Component { state = { obj: { num: 1 } }; onClick = () => { const {obj} = this.state; this.setState({obj}); } render() { console.log('render Parent'); return ( <div className="App" > <button onClick={this.onClick}> 点我 </button> <Child obj={this.state.obj}/> </div> ); } }
点击按钮后,Parent 和 Child 的 render 都会触发。如果将 Child 改为 PureComponent,则 Child 的 render 不会触发,因为 props 还是同一个对象。如果将 Parent 也改为 PureComponent,则 Parent 的 render 也不会触发了,因为 state 还是同一个对象。
- 定义组件时,定义 PropTypes 和 defaultProps
例子如下:
class CategorySelector extends PureComponent { ... } CategorySelector.propTypes = { type: PropTypes.string, catList: PropTypes.array.isRequired, default: PropTypes.bool, }; CategorySelector.defaultProps = { default: false, type: undefined, };
- 避免在 render 里面动态创建对象 / 方法,否则会导致子组件每次都 render
render() { const obj = {num: 1} return( <Child obj={obj} onClick={()=>{...}} /> ); }
在上面代码中,即使 Child 是 PureComponent,由于 obj 和 onClick 每次 render 都是新的对象,Child 也会跟着 render。
- 避免在 JSX 中写复杂的三元表达式,应通过封装函数或组件实现
render() { const a = 8; return ( <div> { a > 0 ? a < 9 ? ... : ... : ... } </div> ); }
避免写像上面这种嵌套的三元表达式。可以写成下面的形式:
f() { ... } render() { const a = 8; return ( <div> { this.f() } </div> ); }
- 多使用解构,如 Function Component 的 props
const MenuItem = ({ menuId, menuText, onClick, activeId, }) => { function onItemClick() { onClick(menuId); } return ( <div menuId={menuId} className={`${style} ${activeId === menuId ? active : ''}`} onClick={onItemClick} > {menuText} </div> ); };
- 如果 props 的数据不会改变,就不需要在 state 或者组件实例属性里拷贝一份
经常会看见这样的代码:
componentWillReceiveProps(nextProps) { this.setState({num: nextProps.num}); } render() { return( <div>{this.state.num}</div> ); }
num 在组件中不会做任何的改变,这种情况下直接使用 this.props.num 就可以了。
- 遵循单一职责原则,使用 HOC / 装饰器 / Render Props 增加职责
比如一个公用的组件,数据来源可能是父组件传过来,又或者是自己主动通过网络请求获取数据。这时候可以先定义一个纯展示型的 Function Component,然后再定义一个高阶组件去获取数据:
function Comp() { ... } class HOC extends PureComponent { async componentDidMount() { const data = fetchData(); this.setState({data}); } render() { return (<Comp data={this.state.data}/>); } }
- 组合优于继承
笔者在真实项目中就用过 2 次以继承的形式写组件,自己写得很爽,代码的复用性也很好,但最大的问题是别人看不懂。我将复用的业务逻辑和 UI 模版都在父类定义好,子类只需要传入一些参数,然后再覆盖父类的几个方法就好(render的时候会用到)。简化的代码如下:
class Parent extends PureComponent { componentDidMount() { this.fetchData(this.url); } fetchData(url) { ... } render() { const data = this.calcData(); return ( <div>{data}</data> ); } } class Child extends Parent { constructor(props) { super(props); this.url = 'http://api'; } calcData() { ... } }
这样的写法从语言的特性和功能实现来说,没有任何问题,最大的问题是不符合 React 的组件编写习惯。父类或者子类肯定有一方是不需要实现 render 方法的,而一般我们看代码都会优先找 render 方法,找不到就慌了。另外就是搞不清楚哪些方法是父类实现的,哪些方法是子类实现的,如果让其他人来维护这份代码,会比较吃力。
继承会让代码难以溯源,定位问题也比较麻烦。所有通过继承实现的组件都可以改写为组合的形式。上面的代码就可以这样改写:
class Parent extends PureComponent { componentDidMount() { this.fetchData(this.props.url); } fetchData(url) { ... } render() { const data = this.props.calcData(this.state); return ( <div>{data}</data> ); } } class Child extends PureComponent { calcData(state) { ... } render() { <Parent url="http://api" calcData={this.calcData}/> } }
这样的代码是不是看起来舒服多了?
三、总结
本文列举了笔者在项目实战和 Code Review 过程中总结的一些最佳实践,只代表个人立场。理解并遵循这些最佳实践,写出来的代码质量都有一定的保证。如果你有不同的意见,或者有补充的最佳实践,欢迎留言。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- vue项目实践004~~~一篮子的实践技巧
- HBase实践 | 阿里云HBase数据安全实践
- Spark 实践:物化视图在 SparkSQL 中的实践
- Spark实践|物化视图在 SparkSQL 中的实践
- HBase实践 | 数据人看Feed流-架构实践
- Kafka从上手到实践-实践真知:搭建Zookeeper集群
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
啊哈C语言!逻辑的挑战(修订版)
啊哈磊 / 电子工业出版社 / 2017-1 / 49
《啊哈C语言!逻辑的挑战(修订版)》是一本非常有趣的编程启蒙书,《啊哈C语言!逻辑的挑战(修订版)》从中小学生的角度来讲述,没有生涩的内容,取而代之的是生动活泼的漫画和风趣幽默的文字。配合超萌的编程软件,《啊哈C语言!逻辑的挑战(修订版)》从开始学习与计算机对话到自己独立制作一个游戏,由浅入深地讲述编程的思维。同时,与计算机展开的逻辑较量一定会让你觉得很有意思。你可以在茶余饭后阅读《啊哈C语言!逻......一起来看看 《啊哈C语言!逻辑的挑战(修订版)》 这本书的介绍吧!