React 开发你必定要知道

JSX 基本语法

1.定义标签时只容许被一个标签包裹
const component = <span>name</span><span>age</span>

2.标签必定要闭合
<span></span>

3.DOM元素属性class和for
class属性改成className   
<div className="myClass"></div>
for属性改成htmlFor 
<label htmlFor="myInput"></label> <input value="a" name="myInput"/>

4.自定义html属性,要使用data-前缀
<div data-attr="xxx"></div>

5.属性值须要使用表达式,只要用{}替换""便可
const person = <Person name={window.isLoggerdIn ? window.name : ''}>

6.html转义
React会将全部要显示到DOM的字符串转义,防止XSS
react提供了dangerouslySetInnerHTML属性,谨慎使用

React 数据流

在React中,数据是自顶向下单向流动的,即从父组件到子组件,这条原则让组件之间的关系变的简单且可预测。state和props是React组件中重要的概念,若是顶层组件初始化props,那么React会向下遍历整棵组件树,从新尝试渲染全部相关的子组件。而state只关心每一个组件本身内部的状态,这些状态只能在组件内部改变,把组件当作一个函数,那么它接受了props做为参数,内部由state做为函数的内部参数,返回一个Virtual DOM的实现。html

组件的state
组件的state是组件的内部状态,state的变化最终将反映到组建UI的变化,咱们在组件的构造方法constructor中经过this.state定义组件的初始状态,并经过this.setState方法改变组件状态(也是改变组件状态的惟一方式),进而组件的UI也会随之从新渲染。react

1.setState是一个异步方法,一个生命周期内全部的setState方法会合并操做。

组件的propses6

1.React的单向数据流,主要的流动管道就是props,
props自己是不可变的。当咱们试图改变props的原始值时,
React会报出类型错误警告,组件的props必定来自于默认属性或者经过父组件传递而来。

2.React为props一样提供了默认的配置。
经过defaultProps静态变量的方式来定义,当组件被调用的时候,默认值保证渲染后始终有值。
    static defaultProps = {
        classPrefix: 'tabs',
        onChange: () => {}    
    }
    
3.proTotypes用于规范props的类型与必需的状态。
若是组件定义了propTypes,那么在开发环境下,就会对组件的props的值类型做检查。
    static propTypes = {
        classPrefix: propTypes.String
    }
    
4.子组件的props,在React中有一个重要且内置的props---children,
它表明组件的子组件集合,children能够根据传入子组件的数量来决定是不是数组类型。

5.用function prop与父组件通信,
父组件能够经过子组件的prop传递给子组件一个回调函数,
子组件须要改变父组件数据时,调用这个回调函数便可。

React生命周期

组件从建立到被销毁的过程称为组件的生命周期。一般,React组件的生命周期能够被分为三个阶段:挂载阶段、更新阶段、卸载阶段数组

1.挂载阶段dom

constructor
这是es6 class的构造方法,组件被建立时,
会首先调用组件的构造方法,
这个构造方法接收一个props参数,props是父组件中传入的属性对象

componentWillMount
该方法在组件被挂载到DOM前调用,且只会被调用一次

render
这是定义组件时惟一必要的方法,该方法根据props和state返回一个react元素
,这个元素用于描述组件的UI,注意render并不负责组件的实际渲染工做,
它只是返回一个UI的描述,真正渲染出页面的DOM的工做有React负责。

componentDidMount 
组件被挂载到DOM后调用,且只会被调用一次

2.更新阶段异步

componentWillReceiveProps(nextProps)
这个方法只在props引发的组件更新过程当中,才会被调用。
state引发的组件更新并不会触发该方法的执。

shouldComponentUpdate(nextProps, nextState)
这个方法决定组件是否继续执行更新过程,当方法返回true时(默认返回值),
组件会继续更新过程。返回false时,组件更新过程中止。

componentWillUpdate(nextProps, nextState)
该方法在组件render调用前调用。

render
该方法根据props和state返回一个react元素,如挂载阶段

componentDidUpdate(preProps, preState)
组件更新后被调用,能够做为操做DOM的地方。两个参数分别是组件更新前的props和state

3.卸载阶段函数

componentWillUnmount
组件被卸载以前调用,此处能够用于清除定时器等,取消监听事件等,避免引发内存泄露。

React refs

ref是react上的特殊属性
在常规的数据流以外强制修改子元素
被修改的能够是react组件实例,或者一个dom元素
能够在dom元素上和类组件上添加ref,react组件在加载时将dom元素传入ref的回调,在componentDidMount 或者componentDidUpdate 这些生命周期前执行。this

1.dom元素上添加refspa

...
handleClick(){
    this.nameInput.focus();
}

render(){
    return(
        <div>
            <input ref={(input)=>{this.nameInput = input;}}
            <button onClick={this.handleClick}>点击获取输入框焦点</button>
        </div>
    );
}

2.react组件上添加refcode

// App.js
otherFunction(){
    this.pager.changePage(5);
}
....
render(){
    return(
        <Pager ref={(page)=>{this.pager = page;}} />
    );
}

// Pager.js
...
changePage(page){
    this.setState({
        page : page
    });
}
...
// 在父组件中使用ref给某一子组件传值,而且子组件调用setState修改自身的状态,
// 该子组件会从新渲染一次,父组件中的其余组件不会从新render

3.ref和函数式组件

function MyTest(){
    let textInput = null;

    function handleClick(){
        textInput.focus();
    }

    return(){
        <div>
            <input ref={(input)=>{textInput=input}/>
            <button onClick={handleClick}>点击获取输入框焦点</button>
        </div>
    }
}
  1. 子组件对父组件暴露dom节点
    // App.js
    ...
    render(){

    return(
        <Sub inputRef={ el => this.inputRef = el; } />
    );

    }

    // Sub.js
    ...
    render(){

    return(){
        <div>
            <input ref={this.props.inputRef} />
        </div>
    }

    }

React forceUpdate

默认状况下,当组件的 state 或 props 改变时,组件将从新渲染。 若是你的 render() 方法依赖于一些其余数据,你能够告诉 React 组件须要经过调用 forceUpdate() 从新渲染。
调用 forceUpdate() 会致使组件跳过 shouldComponentUpdate() ,直接调用 render()。 这将触发子组件的正常生命周期方法,包括每一个子组件的 shouldComponentUpdate() 方法。
forceUpdate就是从新render。有些变量不在state上,可是你又想达到这个变量更新的时候,刷新render;或者state里的某个变量层次太深,更新的时候没有自动触发render。这些时候均可以手动调用forceUpdate自动触发render

// Sub.js
class Sub extends React.Component{
    construcotr(){
        super();
        this.name = "tom";
    }
    refChangeName(name){
        this.name = name;
        this.forceUpdate(); 
    }
    render(){
        return (<div>{this.name}</div>);
    }
}

// App.js
class App extends React.Component{

    handleClick(){
        this.subRef.refChangeName("jack");
    }
    render(){
        return (<div>
            <Sub ref={(sub)=>{this.subRef = sub;}} />
            <button onClick={this.handleClick}>click</button>
        </div>);
    }
}