react 项目总结

前言

最近在写一个项目,在写react的过程当中遇到过不少坑,如今总结一下,为之后的项目做参考.另外借此项目来比较一下 vue.js 和 react.js 之间的一些异同.html

先说说组件

刚刚开始写组件的时候,感受难度不大(跟vue差很少)。最有意思的应该是jsx语法,我的感受,jsx的功能性确实比vue的template更强,并且可读性更高.vue

举个栗子
// vue
<p :id="text" :class="{'active':isActive}" v-text="'hello! ' + msg"></p>
// jsx
<p id={text} className={isActive && 'active'}>hello !{msg}</p>
  1. 在jsx里面没有指令,并且jsx里面 {} 表明要执行的js语句,它的效果相似 return ,它会有返回值.这样的话,更好理解jsx的内容,jsx里面的dom不是真正的dom,只是一种表示dom的语法,{}里面的内容能够彻底理解为js,这种整个jsx就能够完成理解为原生js写的html模版.
  2. 属性计算的部分,vue里面须要在属性名前面加:,在jsx里面则不须要.
  3. 另外,在vue里面的dom的contentText不使用{{}}来渲染,使用由于在vue页面生成以前,模版语法部分没有渲染出来,就会在页面上先出现{{content}},再一闪变成真正的文本内容.
再举个数组遍历渲染的栗子
// vue
<ul>
  <li v-for="(item,index) in list" :key="index" v-if="showItem(item)">
    <span v-text="item.label"></span>
  </li>
</ul>

// vue的methods属性
methods:{
  showItem(item){
    return item.label.indexOf('abc') !== -1
  }
}
// jsx
<ul>
  {list.map((item,index) => {
    return item.label.indexOf('abc') !== -1 && (
      <li key={index}>
        <span>{item.label}</span>
      </li>
    )
  })}
</ul>

你会发现,在一些比较简单渲染需求时,使用vue的template会比较简单直接,并且很易懂.可是若是涉及一些比较复杂的逻辑处理渲染,jsx更直观,由于jsx的语法跟js的差别不大,至关于用js来描述须要如何渲染dom结构.固然jsx并非说能够完成使用js的语法来写dom,{}里面只能是一个表达式,因此像if else或者switch这种语法在{}是不能用的.react

redux

在写redux的时候,不是很习惯。后来慢慢的去适应。因为还用到了saga,以致于书写方法上与redux官方的推荐的有所不一样。vuex

'action type'定义的不一样类型。
  1. action ===> reducer
  2. action ===> saga ===> reducer

第一种状况:触发action以后直接commit一个reducerredux

// action
{type:'do/update-some-data',payload}

第二种状况,触发的action会被saga拦截,而后saga完成必定的操做后(通常是从后台获取数据);put一个action,做用到reducer数组

// saga action
{type:'start/get-some-data',payload}

// reducer action
{type:'success/get-some-data',payload}
{type:'failed/get-some-data',payload}
{type:'error/get-some-data',payload}

一些代码书写规范

由于之前在写代码的时候一直都没有肯定好一个规范,致使代码风格一直有变化(已经被同事吐槽好几回了)。后来在这个项目里面看了其余的同事的代码再结合网上推荐的一些代码规范,目前总结出一些当心得(也不算什么心得)。dom

1.仍是从组件开始

  1. 组件注释
  2. 模块引入
  3. 内部方法
  4. 组件类定义
  5. redux select
  6. export
1.注释的问题我我的一直都重视的,一份好的注释可让别人在开始看代码以前就能对内容有一个大概清晰的了解。
/**
 * @name:组件名称
 * @author:谁维护的
 * @version:2017-12-28 日期或者版本号
 * @description:描述
 * 你会发现没有’param‘,这个部分在组件定义的地方会提到。
 */

这些只是基本的信息,还能够添加其余你想加的内容。函数

2.模块引入的部分通常有这些分类
  1. 依赖。例如库或者插件
  2. 子组件
  3. 资源文件。例如默认的图标或者背景图什么的。
3.内部方法

内部方法通常是针对该组件须要的功能而定义的,并且不想跟类一块儿export出去。好比,组件里拿到后台的一个对象数组,须要根据这个数组的信息计算出一个值,而后在组件中使用。
若是这个方法在多个组件中使用到的话,还能够把它提到utils文件夹中。this

4.组件定义
通常状况下,组件都会使用类来定义。好比:
class MyComponent extends Component{
  static defaultProps = {
    a:0,
    b:1
  }
  constructor(props) {
    super(props)
    this.state = {
      c:2,
      d:3
    }
  }
  handleClick = () = >{
    // some stuff
  }
  render() {
    const {a,b} = this.props
    const {c,d} = this.state
    const e = false
    return(
      <div>
        <div a={a} b={b}></div>
        <div {...{a,c}}></div>
        <div {...this.props} {...this.state}></div>
        e && {<div>some code</div>}
      </div>
    )
  }
}

首先,为啥子要写defaultProps?我以为,有两点:spa

  1. 知道在使用这个组件的时候,应该传入哪些参数,都有什么意义。这样比在组件头注释写更具体。
  2. 设置默认值,避免使用时没有传参,致使一些bug。

state就略过了。

类的方法。这里使用了箭头函数来定义,主要是为了使用this,由于大多数状况下,handle里面都会调用this.setState,这样写就不须要去constructor一个个bind(this)了。其实若是方法里面没有使用指向类的this,用函数定义的方式也是能够的。

render部分。我通常习惯将使用到的propsstate以及其余的数据所有在return前定义出来。这样会更清晰明白组件里面使用了哪些数据。
另外是给元素设置属性的一些小技巧。平时最经常使用的方式是这样的key={value},还可使用对象解构的方式设置属性。

redux seletct & export

说到redux必定要扯上vuex(看完下面的内容,若是有不一样意见的战友,请不要打我)。
这里先从组件部分来看一下reduxvuex的区别。在组件里面主要是看如何让当前组件使用到store中的数据和方法。

// react
import React, { Component } from 'react'
import { connect } from 'react-redux'
import * as actions from '../actions'
import { bindActionCreators } from 'redux'

class MyComponent extends Component{}

function mapStateToProps(state){
  return {
    ...state,
    stateOne:state=>state.stateOne,
    stateTwo:state=>state.stateTwo
    }
}
functino mapDispatchToProps(dispatch){
  return {
    ...bindActionCreators(actions,dispatch),
    handleOne:(arg)=>dispatch(actions.handleOne(arg)),
    handleTwo:(arg)=>dispatch(actions.handleTwo(arg))
  }
}

export connect(mapStateToProps,mapDispatchToProps)(MyComponent)

react里面要使用connect方法把state和dispatcher和当前组件链接起来.

// vue

import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('theModule')

export default {
  computed:{
    ...mapState(['stateOne','stateTwo']),
    ...mapState({
      stateThree:state=>state.theModule.stateThree,
      stateFour:state=>state.theModule.stateFour
    })
  },
  methods:{
    ...mapActions(['handleOne','handleTwo']),
    ...mapActions({
      handleThree:'actionThree',
      handleFour:'actionFour'
    })
  }
}

在vue里面也有相应的辅助函数,并且vuex的store包含来数据和方法,在根组件注入以后,全部的子组件均可以经过this.$store使用,辅助函数只是用来过滤而已.

待续...

相关文章
相关标签/搜索