原文:Our Best Practices for Writing React Components .
这里意译。有些点在之前的文章里提到过:#2
译文地址:https://github.com/YutHelloWo...
如果组件带有state
或者方法,就使用Class写法。
Class写法
如果组件带有state
或者方法,就使用Class写法。
1. 引入CSS
import React,{ Component } from 'react' import { observer } from 'mobx-react' import ExpandableForm from './ExpandableForm' import './styles/ProfileContainer.css'
2. 初始化State
使用ES7句法定义state
import React,{ Component } from 'react' import { observer } from 'mobx-react' import ExpandableForm from './ExpandableForm' import './styles/ProfileContainer.css' export default class ProfileContainer extends Component { state = { expanded: false }
3. 初始化propTypes
和defaultProps
import React,{ Component } from 'react' import { observer } from 'mobx-react' import { string,object } from 'prop-types' import ExpandableForm from './ExpandableForm' import './styles/ProfileContainer.css' export default class ProfileContainer extends Component { state = { expanded: false } static propTypes = { model: object.isrequired,title: string } static defaultProps = { model: { id: 0 },title: 'Your Name' }
propTypes
和defaultProps
的声明应该置顶便于其他开发者阅读。在React v15.3.0版本,推荐使用prop-types这个包替代React.PropTypes。
重要的一点:所有的组件都应当有propTypes验证。
4. 组件内的方法
import React,title: 'Your Name' } handleSubmit = (e) => { e.preventDefault() this.props.model.save() } handleNameChange = (e) => { this.props.model.changeName(e.target.value) } handleExpand = (e) => { e.preventDefault() this.setState({ expanded: !this.state.expanded }) }
使用在方法中箭头函数来替代this.handleExpand.bind(this)
5. this.setState()
是异步的。应该使用函数入参
this.setState(prevState => ({ expanded: !prevState.expanded }))
6. 一个组件或者元素含有多个props
应当分行写
render() { const { model,title } = this.props return ( <ExpandableForm onSubmit={this.handleSubmit} expanded={this.state.expanded} onExpand={this.handleExpand}> <div> <h1>{title}</h1> <input type="text" value={model.name} onChange={this.handleNameChange} placeholder="Your Name"/> </div> </ExpandableForm> ) }
7. 避免在子组件中使用闭包
<input type="text" value={model.name} // onChange={(e) => { model.name = e.target.value }} // ^ Not this. Use the below: onChange={this.handleChange} placeholder="Your Name"/>
8.完整的class
组件写法
import React,object } from 'prop-types' // 分开本地导入和依赖导入 import ExpandableForm from './ExpandableForm' import './styles/ProfileContainer.css' // 使用修饰器(如果有的话) @observer export default class ProfileContainer extends Component { state = { expanded: false } // 初始化state (ES7) 或者在构造函数(constructor)中初始化state (ES6) //使用静态属性(ES7)声明propTypes越早越好 static propTypes = { model: object.isrequired,title: string } // 在propTypes后声明defaultProps static defaultProps = { model: { id: 0 },title: 'Your Name' } // 使用箭头函数绑定指向定义的上下文的this handleSubmit = (e) => { e.preventDefault() this.props.model.save() } handleNameChange = (e) => { this.props.model.name = e.target.value } handleExpand = (e) => { e.preventDefault() this.setState(prevState => ({ expanded: !prevState.expanded })) } render() { // 解构props成可读的 const { model,title } = this.props return ( <ExpandableForm onSubmit={this.handleSubmit} expanded={this.state.expanded} onExpand={this.handleExpand}> // 如果有2个以上props,分行写 <div> <h1>{title}</h1> <input type="text" value={model.name} // onChange={(e) => { model.name = e.target.value }} // 避免创造新的闭包,应该使用下面的方法。 onChange={this.handleNameChange} placeholder="Your Name"/> </div> </ExpandableForm> ) } }
---
函数式组件写法
1. propTypes
import React from 'react' import { observer } from 'mobx-react' import { func,bool } from 'prop-types' import './styles/Form.css' ExpandableForm.propTypes = { onSubmit: func.isrequired,expanded: bool } // Component declaration
2. Destructuring Props and defaultProps
import React from 'react' import { observer } from 'mobx-react' import { func,expanded: bool,onExpand: func.isrequired } function ExpandableForm(props) { const formStyle = props.expanded ? {height: 'auto'} : {height: 0} return ( <form style={formStyle} onSubmit={props.onSubmit}> {props.children} <button onClick={props.onExpand}>Expand</button> </form> ) }
结合ES6的函数入参解构,可以如下书写
import React from 'react' import { observer } from 'mobx-react' import { func,onExpand: func.isrequired } function ExpandableForm({ onExpand,expanded = false,children,onSubmit }) { const formStyle = expanded ? {height: 'auto'} : {height: 0} return ( <form style={formStyle} onSubmit={onSubmit}> {children} <button onClick={onExpand}>Expand</button> </form> ) }
3. 避免箭头函数写法
const ExpandableForm = ({ onExpand,expanded,children }) => {
4. 高阶组件
import React from 'react' import { observer } from 'mobx-react' import { func,onSubmit }) { const formStyle = expanded ? {height: 'auto'} : {height: 0} return ( <form style={formStyle} onSubmit={onSubmit}> {children} <button onClick={onExpand}>Expand</button> </form> ) } export default observer(ExpandableForm)
5. 完整代码
import React from 'react' import { observer } from 'mobx-react' import { func,bool } from 'prop-types' // Separate local imports from dependencies import './styles/Form.css' // 在组件前声明propTypes ExpandableForm.propTypes = { onSubmit: func.isrequired,onExpand: func.isrequired } // 解构props,通过函数入参默认值的方式设定defaultProps function ExpandableForm({ onExpand,onSubmit }) { const formStyle = expanded ? { height: 'auto' } : { height: 0 } return ( <form style={formStyle} onSubmit={onSubmit}> {children} <button onClick={onExpand}>Expand</button> </form> ) } // Wrap the component instead of decorating it export default observer(ExpandableForm)原文链接:https://www.f2er.com/react/303113.html