深入react技术栈笔记

580 阅读6分钟

1. 属性dangerouslySetInnerHTML直接渲染字符串为html

2. React.Children.map或.forEach或.count都是React提供的便利的方法,用以处理children。

3. 组件间的通信

  • 父组件向子组件通信用props,
  • 子组件向父组件通信用回调函数
  • 跨组件通信得用全局事件,广播

4. 组件所有生命周期及属性

import React, { Component, PropTypes } from 'react'

class App extends Component {
   
    static propTypes = {
        // 类型约束
    }
    
    static defaultProps = {
        // 默认props
    }
    
    constructor(props) {
        super(props);
        this.state = {
            //初始化state
        }
    }
    
    //以下生命周报将会依次执行
    
    componentWillMount() {
        // 组件将挂载前执行
        // 挂载前初始化动作
    }
    
    componentDidMount() {
        // 组件挂载后执行
        // 有时需要挂载后才能获取的属性,比如宽高,位置
    }
    
    componentWillReceiveProps(nextProps) {
        // 组件将会接收到从父组件传来的新props
        // 即组件的props变化后,根据新props更新state
        // this.setState({})
    }
    
    sholdComponentUpdate(nextProps,nextState) {
        // 组件是否要更新并重新渲染
        // 默认是每次props,state变化就重新渲染,但此方法允许我们对新props或新state进行判断,识别,返回false则会阻止渲染,提高性能
        // return true
    }
    
    componentWillUpdate(nextProps,nextState) {
        // 组件将要更新
        // 我觉得this.props是旧props,nextProps是新props, state同
        // 以便我们能根据新旧值进行一些处理
    }
    
        componentDidUpdate(prevProps,prevState) {
        // 组件已经更新
        // 我觉得this.props是新props,prevProps是旧props, state同
        // 以便我们能根据新旧值进行一些处理
    }
    
    componentWillUnmount() {
        // 组件卸载前执行
        // 执行清理,回收
    }
}

5. 无状态组件和有状态组件

  • 直接返回html的函数是无状态组件
  • class构造的是有状态组件 无状态组件不会有生命周期 使用Recompose库的pure方法可以传入无状态组件,包装返回有状态组件

6. 在react使用refs获取组件挂载后的DOM实例,可添加原生事件,但要记得在将要卸载前移除原生事件。

7. 表单

  • 受控组件要有value或checked 和 onChange input和select 受控组件要有value属性 option 有selected属性 radio和checkbox 受控组件要有checked属性

  • 非受控组件要有defaultValue或defaultChecked 用ref操作原生DOM defaultValue和defaultCheced 只会渲染一次,在后续的渲染时并不起作用

8.样式

1.样式中的像素值

以px为单位的样式,可以不用加px,直接使用数字

2.react中的classname

实际就是普通元素中的class,接受字符串参数,普通用法得自己拼接字符串

可以使用classname库,像vue那样根据布尔值决定是否显示相应的class

const buttonClass = classname({active: true, disabled: true})
  1. scss中的变量可以输出到js

    import style form 'config.scss';
    
    console.log(style.primary) // #eee
    
使用css modules
  • 1.使用 import style from './Button.css'; 1 相当于1 css modules会自动添加hash,以避免样式重复

  • 2.css modules的css文件中写样式,默认是local

    .normal{} 等同于 :local(.normal){}
    
    // 如果想定义全局样式
    :global(.btn){}
    
    // 如果想定义多个全局样式
    :global{
        .btn{}
        .btn2{}
    }
    
    //如果想复用样式,使用composes
      .base{}
    .normal{
        composes: base;//这样就能插入base的样式
    }
    .normal{
        composes: $base from './settings.css';//这样就能从别的文件中插入base的样式
    }
    
    

9.react组件构建的三种方法

    1. React.createClass()
const Button = React.createClass({
    getDefaultProps(){
        return {
            color: 'blue',
            text: 'confirm'
        };
    },

    render(){
        const {color,text} = this.props;
        return (
            <button className={'btn btn-${color}'}>{text}</button>
        )
    }
})

这个是最原始,兼容性最高的创建方法 getDefaultProps会返回color,text的值给 this.props 在渲染时,再把this.props的值解构赋值给{color,text}。这样现在才能使用这两个变量 每次使用Button组件时,都会调用该方法生成实例

  • 2.ES6 classes 的写法
import React, { Component } from 'react';

class Button extends Component {
   constructor(props){
        super(props);
   }
   
   static defaultProps = {
        color: 'blue',
        text: 'confirm'
   };
   
   render(){
       const {color,text} = this.props;
        return (
            <button className={'btn btn-${color}'}>{text}</button>
        )
   }
}

static defaultProps定义默认属性值,contructor初始化构造(如果属性有默认值,则引用默认值,如果属性在组件上定义了,则引用定义的),最后渲染时,也仍然需要把属性解构赋值出来const {color,text} = this.props;这样才能在组件中使用上这些变量 每次使用Button组件时,都会调用该方法生成实例

  • 3.无状态函数
function Button({color='blue',text='confirm'}){
    return (
        <button className={'btn btn-${color}'>{text}</button>
    )
}

无状态组件只传入props,和context两个参数,不存在state,也就没有生命周期,但仍然还有propTypes和defaultProps静态方法 在合适的情况下,能使用无状态函数就使用无状态函数,因为无论这个组件调用多少次,他始终保持着一个实例。

10.props中可以传递组件作为属性

function Button({color='blue',childComp='<div>子组件</div>'}){
    return (
        <button className={'btn btn-${color}'>{childComp}</button>
    )
}

11.react中事件和html中的事件绑定区别

react中元素事件得用onClick这样的驼峰式写法 html中的元素事件是用onclick全小写的写法

react中支持各种属性值 onClick={this.handleClick} 而html中只支持 onclick="handleClick()";

12.react中的事件是直接绑定在最外层,然后由最外层分配事件给子组件

13.react中绑定事件的三种方法

  • 1.自动绑定
class App extends Component {

    static handleClick(e, arg) {
        console.log(e, arg);
    }

    render() {
        return (
            <div className="App">
                <button onClick={App.handleClick.bind(this, 'text1')}>1</button>
            </div>
        );
    }
}
  • 2.在构造器中绑定
class App extends Component {
    contructor(props){
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    static handleClick(e, arg) {
        console.log(e, arg);
    }

    render() {
        return (
            <div className="App">
                <button onClick={this.handleClick}>1</button>
            </div>
        );
    }
}
  • 3.箭头函数(默认绑定当前环境的this)
class App extends Component {
    handleClick(e, arg)=>{
        console.log(e, arg);
    }

    render() {
        return (
            <div className="App">
                <button onClick={this.handleClick}>1</button>
            </div>
        );
    }
}

14.mixin

就是把外库属性混入当前组件

React.createClass({

​ mixins: [xxx],

​ render(){}

})

或安装minxin装饰插件

@minxin(PureRender, Theme)

class MyComponent extends Component {

}

mixin缺点
  • 破坏原有组件封装
  • 命名冲突
  • 增加复杂性

所以最新的react已经建议不使用mixin,而是换用高阶组件

15. 高阶组件

  • 属性代理

  • 控制props

  • 通过refs使用引用

  • 抽象state

我觉得就是通过某个函数或装饰器或外层组件包裹低级组件,给低级组件添加增强属性,增强组件。

16. lodash.js

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库

17.Immutable.js

Immutable库,PureRender库,react-immutable-render-mixin, react-css-modules, react motion 不可变数据,高效对比

17.1 React性能优化总结

segmentfault.com/a/119000000…

// 在react的checkbox组件中测试
// 继承React.Component,输出13个1和13个2
// 继承React.PureComponent,输出13个1和6个2
// 减少了一半的重复渲染
    componentWillReceiveProps(props) {
      console.log(1)
    }

    componentDidUpdate(prevProps, prevState) {
     console.log(2)
    }

18.循环迭代组件时key属性的作用

key用来标识当前组件的唯一性

  • 错误的做法,使用序号或随机值作为key, 低效
  • 正确的做法,使用数据中的唯一id或唯一值作为key,高效

19. react-addons-perf react性能测试

20.vivus.js SVG线条动画

21.css动画

React 提供了一个 ReactTransitionGroup 插件作为动画的底层API,和一个 ReactCSSTransitionGroup 用于轻松实现基础的CSS动画和过渡。 github.com/reactjs/rea… 使用方法基本和vue差不多

22.three.js 3D动画

23.react-motion库,使用js实现动画,更加优美的缓动

24.自动化测试

  • jest
  • 浅渲染机制(只渲染和测试组件第一层,子组件应该在子组件中测试)
  • 全渲染机制(完整渲染后,再测试)
  1. JSDOM: js 模拟DOM环境
  2. Cheerio: 类似JSDOM,类似JQuery语法
  3. Karma: 真实浏览器中执行测试,使用真实的DOM

其中Cheerio即Enzyme是Airbnb开源的React组件测试框架,这个可以优先和重点看看。