React

一、JSX
1、JSX是js的一种扩展语法,既不是字符串又不是html,它是一种特殊的表达式

const element = <div>hello~</div>

2、可以当做参数函数,也可以作为函数的返回值

3、JSX可以防止注入攻击(JSX在渲染之前都是被转转义字符串)

4、JSX实际上是在执行React.createElement(),是通过Babel实现的

二、dom渲染

1、相对浏览器dom渲染,react的dom渲染开销较小,因每次只会重新渲染更新的部分,与其实现原理有关,此时用到diff算法

三、组件分类、props

1、函数式组件

function Func(props){
  return  <div>{props.name}~<div>               
}

2、class组件

class Cla extends React.Component{
  constructor(props){
    super(props)
}  
   render(){
     return <div>{this.props.name}<div>
} 
}            

3、原生dom标签

  附加信息:

  1、当react元素为自定义组件时,JSX会将组件属性(attributes)转换成props传给组件

const element = <Cla name="Lily"></Cla>

  此时,Cla类中的props为:名为props的对象

props = {name: "Lily"}

  2、当组件本身很复杂时、复用率较高时,建议提取出可复用的组件,这样便于代码的可维护性,代码更简洁

4、props具有只读性,不可更改

四、state

1、不可变性,不可直接直接修改

2、唯一可定义性,只能在construtor函数中定义,并且每次修改必须通过setstate返回新的对象来实现修改

3、局部性(封装性),仅对当前class有效

4、单项数据流,组件之间的数据通信都是“自上而下”的瀑布形式,子组件无法知道props是来自父组件的state or props or 手写的变量

5、独立性,有状态的组件和无状态的组件之间可以相互嵌套,互不影响

ReactDOM.render(
    <div>
        <App />
        <App />
        <App />
    </div>,
    document.getElementById('root')
);

此时,dom会有生成三个独立的计时器,虽然他们的时间是相同的

五、组件的提取与封装

1、定义一个原始的时钟组件(这样,每次都会通过调用ReactDom.render来改变时间

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component{
    constructor(props){
        super(props)
    }

    render() {
        return (
            <div>
                hello,word!
                <p>{this.props.dateId}</p>
            </div>
        );
    }
}

function Clock() {
    ReactDOM.render(
        <App dateId={new Date().toLocaleTimeString()}/>,
        document.getElementById('root')
    );
}

setInterval(()=>{
    Clock()
},1000)

设想:有没有一种方法可以每次让组件自己自动更新,二只调用一次ReactDom.render函数(答案当然是可以的),于是有了组件的提取与封装,这样,每次可以实现组件的复用性,并且可以实现每次更改让组件自己自动更新

2、封装组件,将自定义组件的attributes写到其函数(class)里面

3、时钟也要写在组件里面,供每次setstate改变内部state,通常改变数据写在componentDidMount函数中(在dom渲染完成后调用),并且,在componentWillUnmount函数中清除时钟编译器

class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            dateId: new Date().toLocaleTimeString()
        }
    }

    componentDidMount(){
        // 每次页面渲染完成后调用,通常在次函数中,更改下次渲染改变的数据,
        // 通常异步执行也在此函数中执行
        this.timerId = setInterval(()=>{
            this.setState({
                dateId: new Date().toLocaleTimeString()
            })
        },1000)
    }

    componentWillUnmount(){
        // clock组件被删除时,应该清楚定时器
        clearInterval(this.timerId)
    }

    render() {
        return (
            <div>
                hello,word!
                <p>{this.state.dateId}</p>
            </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
);

误区:组件封装前后,实际上dom重新渲染的地方相同,此时diff的时间算法复杂度是相同的,并不存在,组件封装之后重新渲染的dom节点更少,当dom树(一般都是数据改变)发生改变时,才会被重新渲染

六、

posted @ 2019-05-21 23:06  于爱梅  阅读(157)  评论(0编辑  收藏  举报