zoukankan      html  css  js  c++  java
  • React入门

    虚拟dom、jsx

    • 从 JSX 到页面到底经过了什么样的过程:

    image

    1. JSX 是 JavaScript 语言的一种语法扩展,长得像 HTML,但并不是 HTML。
    2. React.js 可以用 JSX 来描述你的组件长什么样的。
    3. JSX 在编译的时候会变成相应的 JavaScript 对象描述。
    4. react-dom 负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,并且渲染到页面上。

    虚拟dom:

    1. state异步合并:改变 state 数据时,由于 setState 是一个异步函数,当你一次调用多个 setState 时,React 并不会生成多次虚拟 DOM 而是将多次 setState 合并,然后生成一次虚拟 DOM 进行比对

    2. js对比渲染:新的虚拟 DOM 与原来的虚拟 DOM 进行比对时,它会进行同层比较,即相同的节点层进行比较,如果不同则直接将原始虚拟 DOM 中该节点层及以下的节点全部删除,重新生成新的虚拟 DOM 节点,而不会继续向下比对

    3. 循环需要加key:你在 JSX 模板中遍历 state 中某个数据时,为什么不加 key 值浏览器会报错,这是因为你不再遍历的每条数据加上 key 值,更改 state 中那条数据的值,生成虚拟 DOM 后,React 就不知道原始遍历的数据和这次更新后遍历的数据一一对应的关系,就会再次重新渲染,而加上 key 值,它则能迅速比对出有差异的部分进行部分的更新。

    4. 为什么不建议用 index 作为 key 值:因为当你插入 / 删除中间的数据时,从改变的那个数据开始,后续每个数据的 index 值就会变,从而就导致了每个数据的 key 值相应变化了,这样依旧会引起大规模渲染,这就是其中的原因

    // 普通的代码
    <div class='box' id='content'>
      <div class='title'>Hello</div>
      <button>Click</button>
    </div>
    
    // 代码对应转化出来的js
    // HTML 的信息和 JavaScript 所包含的结构和信息其实是一样的,我们可以用 JavaScript 对象来描述所有能用 HTML 表示的 UI 信息
    {
      tag: 'div',
      attrs: { className: 'box', id: 'content'},
      children: [
        {
          tag: 'div',
          arrts: { className: 'title' },
          children: ['Hello']
        },
        {
          tag: 'button',
          attrs: null,
          children: ['Click']
        }
      ]
    }
    
    
    // 编译后的代码
    // React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等。
    class Header extends Component {
      render () {
        return (
         React.createElement(
                   'div',
                   { 'class': 'box', id: 'content' },
                   React.createElement(
                      'div',
                      { 'class': 'title' },
                      'Hello'
                   ),
                   React.createElement(
                      'button',
                      null,
                      'Click'
                )
            )
        )
      }
    }
    
    

    render(不要在render里setState)

    1. 一个组件类必须要实现一个 render 方法。
    2. 这个 render 方法必须要返回一个 JSX 元素。
    3. 必须要用一个外层的 JSX 元素把所有内容包裹起来。
    // 错误
    render () {
      return (
        <div>第一个</div>
        <div>第二个</div>
      )
    }
    
    // 正确
    render () {
      return (
        <div>
          <div>第一个</div>
          <div>第二个</div>
        </div>
      )
    }
    
    // 定义常量
    render () {
      const className = 'header';
      const isGoodWord = true;
      return (
        <div className={className}>
          <h1>React 小书</h1>
           {isGoodWord
              ? <strong> is good</strong>
              : <span> is not good</span>
            }
        </div>
      )
    }
    

    生命周期

    class Header extends Component {
      constructor () {
        super()
        // 最早渲染
        console.log('construct')
      }
      // 组件挂载开始之前,也就是在组件调用 render 方法之前调用。
      componentWillMount () {
        console.log('component will mount')
      }
      // 组件挂载完成以后,也就是 DOM 元素已经插入页面后调用。
      componentDidMount () {
        console.log('component did mount')
      }
      render () {
        console.log('render')
        return (
          <div>
            <h1 className='title'>React 小书</h1>
          </div>
        )
      }
    }
    // 控制台输出
    construct
    component will mount
    render
    component did mount
    
    
    // 性能优化
    // 你可以通过这个方法控制组件是否重新渲染。如果返回 false 组件就不会重新渲染。
    shouldComponentUpdate(nextProps, nextState){
         // 值没有发生过变化,不需要重新触发render
         if(nextState.Number == this.state.Number){
            return false
         }
    }
    
    // 组件收到新的 props 之前调用
    componentWillReceiveProps(nextProps){
       
    }
    
    componentWillUpdate():组件开始重新渲染之前调用。
    
    componentDidUpdate():组件重新渲染并且把更改变更到真实的 DOM 以后调用。
    
    
    // 组件对应的 DOM 元素从页面中删除之前调用。常用于离开页面清除定时器
    componentWillUnmount(){
      console.log('component will unmount')
    }
    

    dom操作之ref

    以前我们通过手动 DOM 操作进行页面更新(例如借助 jQuery),而在 React.js 当中可以直接通过 setState 的方式重新渲染组件,渲染的时候可以把新的 props 传递给子组件,从而达到页面更新的效果。

    // 我们给 input 元素加了一个 ref 属性,这个属性值是一个函数。
    // 当 input元素在页面上挂载完成以后,React.js就会调用这个函数,
    // 并且把这个挂载以后的 DOM 节点传给这个函数。
    // 在函数中我们把这个 DOM元素设置为组件实例的一个属性,
    // 这样以后我们就可以通过 this.input 获取到这个 DOM 元素
    class AutoFocusInput extends Component {
      componentDidMount () {
        this.input.focus()
      }
    
      render () {
        return (
          <input ref={(input) => this.input = input} />
        )
      }
    }
    

    组件

    • class组件
    import React from 'react'
    
    import ReactDOM from 'react-dom'
    
    class App extends React.Component{
        render(){
            return(
            //此处的this指的就是App组件,自定义在App上的属性就在this的props上
                console.log(this),
                <h1>Hello {this.props.name}React!</h1>
            )
        }
    }
    

    less语法

    // 设置行内样式
    // 之前html的写法
    <h1 style='font-size: 12px; color: red;'>React.js 小书</h1>
    // react的写法,参数驼峰
    <h1 style={{fontSize: '12px', color: 'red'}}>React.js 小书</h1>
    
    • 数据流(props、state)
    1. props
    2. state
      使用方式:1 初始化state 2 setState修改state
    • 注意:使用 setState() 方法修改状态,状态改变后,React会重新渲染组件
    • 注意:不要直接修改state属性的值,这样不会重新渲染组件!!!
    • 事件

    父子组件传值

    案例讲解

    • 定义一个自定义组件
    • 组件封装
    • 父子组件传值
  • 相关阅读:
    1015,存储过程,视图
    1009,数据库查询,聚合函数,日期时间函数
    1008,数据库表格创建,名称,格式

    公历和农历转换的JS代码
    面向对象之封装
    HTML之锚点
    HTML之css+div
    HTML基础
    SQL之定义变量
  • 原文地址:https://www.cnblogs.com/Hsong/p/13826331.html
Copyright © 2011-2022 走看看