资讯专栏INFORMATION COLUMN

[译]React Component最佳实践

Alfred / 2765人阅读

摘要:引入初始化使用句法定义初始化和和的声明应该置顶便于其他开发者阅读。在版本,推荐使用这个包替代。组件内的方法使用在方法中箭头函数来替代是异步的。高阶组件完整代码在组件前声明解构通过函数入参默认值的方式设定

原文: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. 初始化propTypesdefaultProps
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"
  }

propTypesdefaultProps的声明应该置顶便于其他开发者阅读。在React v15.3.0版本,推荐使用prop-types这个包替代React.PropTypes。
重要的一点:所有的组件都应当有propTypes验证。

4. 组件内的方法
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"
  }
  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 ( 
      
        

{title}

) }
7. 避免在子组件中使用闭包
  { model.name = e.target.value }}
            // ^ Not this. Use the below:
            onChange={this.handleChange}
            placeholder="Your Name"/>
8.完整的class组件写法
import React, { Component } from "react"
import { observer } from "mobx-react"
import { string, 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 ( 
      
        // 如果有2个以上props,分行写
        

{title}

{ model.name = e.target.value }} // 避免创造新的闭包,应该使用下面的方法。 onChange={this.handleNameChange} placeholder="Your Name"/>
) } }

---

函数式组件写法 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, bool } from "prop-types"
import "./styles/Form.css"
ExpandableForm.propTypes = {
  onSubmit: func.isRequired,
  expanded: bool,
  onExpand: func.isRequired
}
function ExpandableForm(props) {
  const formStyle = props.expanded ? {height: "auto"} : {height: 0}
  return (
    
{props.children}
) }

结合ES6的函数入参解构,可以如下书写

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,
  onExpand: func.isRequired
}
function ExpandableForm({ onExpand, expanded = false, children, onSubmit }) {
  const formStyle = expanded ? {height: "auto"} : {height: 0}
  return (
    
{children}
) }
3. 避免箭头函数写法
const ExpandableForm = ({ onExpand, expanded, children }) => {

虽然语法没问题,但是这里函数是匿名函数。

4. 高阶组件
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,
  onExpand: func.isRequired
}
function ExpandableForm({ onExpand, expanded = false, children, onSubmit }) {
  const formStyle = expanded ? {height: "auto"} : {height: 0}
  return (
    
{children}
) } 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,
  expanded: bool,
  onExpand: func.isRequired
}

// 解构props,通过函数入参默认值的方式设定defaultProps
function ExpandableForm({ onExpand, expanded = false, children, onSubmit }) {
  const formStyle = expanded ? { height: "auto" } : { height: 0 }
  return (
    
{children}
) } // Wrap the component instead of decorating it export default observer(ExpandableForm)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91432.html

相关文章

  • 】TypeScript中的React高阶组件

    摘要:原文链接高阶组件在中是组件复用的一个强大工具。在本文中,高阶组件将会被分为两种基本模式,我们将其命名为和用附加的功能来包裹组件。这里我们使用泛型表示传递到的组件的。在这里,我们定义从返回的组件,并指定该组件将包括传入组件的和的。 原文链接:https://medium.com/@jrwebdev/... 高阶组件(HOCs)在React中是组件复用的一个强大工具。但是,经常有开发者在...

    wizChen 评论0 收藏0
  • 程序员练级攻略(2018):前端性能优化和框架

    摘要:,谷歌给的一份性能指南和最佳实践。目前而言,前端社区有三大框架和。随后重点讲述了和两大前端框架,给出了大量的文章教程和相关资源列表。我认为,使用函数式编程方式,更加符合后端程序员的思路,而是更符合前端工程师习惯的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 这个是我订阅 陈皓老师在极客上的专栏《左耳听风》...

    VEIGHTZ 评论0 收藏0
  • 程序员练级攻略(2018):前端性能优化和框架

    摘要:,谷歌给的一份性能指南和最佳实践。目前而言,前端社区有三大框架和。随后重点讲述了和两大前端框架,给出了大量的文章教程和相关资源列表。我认为,使用函数式编程方式,更加符合后端程序员的思路,而是更符合前端工程师习惯的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 这个是我订阅 陈皓老师在极客上的专栏《左耳听风》...

    CoffeX 评论0 收藏0
  • [] 逐渐去掌握 React(作为一名 Angular 开发者)

    摘要:你是一个对感兴趣的开发者吗不用担心,这真的不会让你成为一个背叛者或其他什么,真的。事实上,这个想法并不是或独创的它只是一种很棒的软件开发实践方式。把代码分离到不同的文件里并不会自动导致关注点分离。 原文链接 : Getting to Grips with React (as an Angular developer)原文作者 : DAVE CEDDIA译者 : 李林璞(web前端领域)...

    channg 评论0 收藏0
  • 】Redux 还是 Mobx,让我来解决你的困惑!

    摘要:我现在写的这些是为了解决和这两个状态管理库之间的困惑。这甚至是危险的,因为这部分人将无法体验和这些库所要解决的问题。这肯定是要第一时间解决的问题。函数式编程是不断上升的范式,但对于大部分开发者来说是新奇的。规模持续增长的应 原文地址:Redux or MobX: An attempt to dissolve the Confusion 原文作者:rwieruch 我在去年大量的使用...

    txgcwm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<