React01

React01

React属于前端 三大框架: Vue Angular React

  • vue: 开源社区
  • react: Facebook
  • angular: Google

React编写 分两种方式:

  • 脚本方式
    • 适合入门: 类似于 jQuery的使用
  • 脚手架方式
    • 适合实际工作. 类似于 vue angular 的使用

React

官方: https://react.docschina.org/

官方脚本:

有些地区网络 可能无法访问

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

国内脚本地址:

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>

本地js文件: 到FTP获取

JSX

在原生 JS 的语法上, 只能利用函数封装实现简化操作: 然而这种语法并不够简单

Facebook工程师, 设计了新的语法糖, 来简化代码 – JSX

JSX: 就是能够在 脚本中 书写 的 XML 代码

但是这种写法 浏览器不能识别, 必须进行转化: babel

https://www.babeljs.cn/

脚本地址:

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

发展过程

  • 原生DOM操作
    • 需要一步一步一步…来写
      • 创建元素->设置各种属性->设置内容 -> 找到要添加到哪里-> 添加上
  • React操作
    • 利用函数封装语法, 对创建元素过程进行了简化
      • 发现: 语法不够简单
  • JSX
    • 创建新的语法: JSX 在 脚本中书写 XML 代码
    • 真正运行时, 需要babel 编译回 原生的JS代码

组件

React项目 也是 SPA: Single web Page Application 单页应用

组件: 组成页面的零件 – 复用性特征

  • 函数: 简单组件
  • 类: 复杂组件

事件

只有能够支持复杂操作的 类方式 组件才可以

<标签  on事件名={} />

脚手架方式

实际开发时常用

  • 安装脚手架

    • 确保npm的中国镜像

      # 查看镜像:  有taobao字样就OK
      npm config get registry
      
      # 设置镜像
      npm config set registry http://registry.npm.taobao.org/
      
    • 安装脚手架

      npm i -g create-react-app
      

      常见错误: Error: File Exists 说明已经安装过, 直接使用即可!

      或者参考 angular01 的笔记, 删除旧的 再安装新的

  • 生成项目包: 注意执行cmd所在的目录下生成

    create-react-app 包名
    例如: create-react-app react_pro
    
  • 启动项目: 在项目下执行

    npm start
    

启动流程

  • 启动服务器: npm start
    • 启动了唯一标识 是 3000 端口的服务器
  • 在浏览器中访问: localhost:3000
  • 服务器默认设定: 自动提供 index.html 给来访用户
  • index.html: 存在 <div id="root"></div> 标签
  • webpack: 脚手架自带 webpack 打包工具, 默认设定: 把 index.js 文件打包到 index.html 中
  • index.js: 使用 ReactDOM.render() 挂载了App.js 到 id=‘root’ 的标签中
  • App.js 就是根组件

State状态值

微信小程序中的 data 和 setData() 就是模仿的 React 的状态值机制.

React中:

  • state: 保存的值 可以显示到页面上
  • setState: 配合此方法, 更新数据同时 可以更新UI
// 状态值 state

// rcc
import React, { Component } from "react";

export default class App extends Component {
  // state 负责存储 界面上变化的值.  配合 setState 实现变化
  state = { num: 1 };

  doAdd = () => {
    this.setState({ num: this.state.num + 1 });
  };

  doMinus = () => {
    this.setState({ num: this.state.num - 1 });
  };

  render() {
    return (
      <div>
        <button onClick={this.doMinus}>-</button>
        <div>{this.state.num}</div>
        <button onClick={this.doAdd}>+</button>
      </div>
    );
  }
}

// 详说:事件中的this指向

// rcc
import React, { Component } from "react";

export default class App extends Component {
  state = { num: 1 };

  /**
   * 函数中的this指向:
   * 普通函数: xxx.show();   show()中的this 就是 xxx;  this指向函数的调用者.
   *    墙头草 随风倒
   * 箭头函数: =>   xxx.show();  箭头函数中的this与声明时所在位置一样, 和调用者无关;
   *    忠贞. 身在曹营心在汉
   */
  doAdd() {
    this.setState({ num: this.state.num + 1 });
  }

  render() {
    return (
      <div>
        {/* 点击时: 打  然然的媳妇;  谁打的? */}
        {/* 点击时: 调用 当前对象的 doAdd 方法 --  事件是 window 触发的.  
        window触发的函数 其this指向就是undefined */}

        {/* 解决办法1: 指定 doAdd 中的this --- bind */}
        <button onClick={this.doAdd.bind(this)}>{this.state.num}</button>

        {/* 解决办法2: 利用箭头函数的 this 保存机制 */}
        {/* 语法糖: ()=> { return this.doAdd() }  简化成  ()=> this.doAdd() */}
        {/* 原理: 点击时 执行的箭头函数, 箭头函数再执行方法 */}
        <button onClick={() => this.doAdd()}>{this.state.num}</button>
      </div>
    );
  }
}

State的异步性

// 详说: setState
// rcc

import React, { Component } from "react";

export default class App extends Component {
  state = { num: 1 };

  doAdd() {
    // 1. 黄色警告: 不要直接修改 state 中的值, 必须用 setState来改
    // 2. a = 5;  b = a++;  b是5  a是6
    // 3. setState 是异步的
    this.setState({ num: this.state.num++ }, () => {
      //参数2: 回调函数:  刷新UI完毕后自动触发
      console.log("UI更新操作结束: 数据num:", this.state.num);
    });

    // setState()要做两件事
    // 1. 更新数据
    // 2. 刷新UI -- 慢 cpu->GPU显卡->重绘...

    console.log(this.state.num);
  }

  render() {
    return (
      <div>
        <button onClick={this.doAdd.bind(this)}>{this.state.num}</button>
      </div>
    );
  }
}

State的更新作用

// setState 特殊用法
// rcc

import React, { Component } from "react";

export default class App extends Component {
  //setState()做两件事:  更新UI  和 更新数据
  num = 1; //实际使用时, 数据不放state 也可以利用 setState() 刷新页面

  doAdd() {
    this.num++;

    this.setState({}); //更新UI 不更新数据: 参数必须填, 空对象即可!

    console.log(this.num);
  }

  render() {
    return (
      <div>
        <button onClick={this.doAdd.bind(this)}>更新 {this.num}</button>
      </div>
    );
  }
}

动态样式

vue中: :style="{属性名:值}"

angular中: [ngStyle]="{属性名:值}"

// 动态样式:
// 内联 和 外部

// rcc
import React, { Component } from "react";

export default class App extends Component {
  state = { size: 18 };

  render() {
    return (
      <div>
        <button onClick={() => this.setState({ size: this.state.size + 2 })}>
          变大
        </button>
        {/* 内联样式的值: 对象类型 */}
        <span
          style={{
            color: "red",
            fontSize: this.state.size + "px",
            backgroundColor: "lightgray",
            padding: "10px",
            borderRadius: "4px",
            margin: "4px",
            display: "inline-block",
          }}
        >
          成功
        </span>
      </div>
    );
  }
}

外部class

// 外部样式
// rcc

import React, { Component } from "react";

/**
 * 外部css文件的引入
 *
 * html引入: <link ...
 * css 引入: @import 'css路径'
 * js  引入: import 'css文件'
 *    注意: 必须带有 路径标识 ./  / ../  否则会识别为模块;  带路径标识才会识别为文件
 */
import "./App.css";

export default class App extends Component {
  render() {
    return (
      <div>
        {/* JSX是 DOM 的语法糖: DOM原生操作中 就是 className 属性名 */}
        <span className="danger">DANGER</span>
      </div>
    );
  }
}

双向数据绑定

vue: v-model

angular: [(ngModel)]

// 双向数据绑定

// rcc

import React, { Component } from "react";

export default class App extends Component {
  // 变化的数据 && 影响UI  -- 必须放state
  state = { word: "123456" };

  // 约定俗成的规范: 事件触发的函数 带有_开头;  这样读代码时 就能看出来哪些方法是事件触发的
  _onChange(event) {
    // 事件触发的函数, 都会自动接收事件作为 最后的参数
    // console.log(event);
    let word = event.target.value;
    console.log(word);

    //更新给数据 && 刷新UI
    // this.setState({ word: value });
    // 语法糖: { aaa: aaa } => { aaa }

    this.setState({ word });
  }

  render() {
    return (
      <div>
        {/* 报错: 绑定了变量给value属性, 导致输入框不能变动 -- 此时要选 这个输入框是 只读的 readOnly 还是 双向绑定 onChange */}
        <input type="text" value={this.state.word} readOnly />
        <br />
        {/* onChange: 双向绑定的方向2 -- 数据变化时 */}
        <input
          type="text"
          value={this.state.word}
          onChange={this._onChange.bind(this)}
        />
        <hr />
        {/* 懒: 懒得声明函数 可以直接箭头函数写到JSX里 */}
        <input
          type="text"
          value={this.state.word}
          onChange={(event) => this.setState({ word: event.target.value })}
        />

        <p>{this.state.word}</p>
      </div>
    );
  }
}

事件传参

// 事件传参

// rcc
import React, { Component } from "react";

export default class App extends Component {
  state = { item: "" };

  _chooseItem(item) {
    // 故意参数名item 和 state.item 同名,  凑语法糖
    this.setState({ item });
  }

  render() {
    return (
      <div>
        <span>然然最喜欢的项目: {this.state.item}</span>
        <hr />
        {/* 解决方案1: bind提前绑定参数, 点击后自动传入 */}
        <button onClick={this._chooseItem.bind(this, "吃饭")}>吃饭</button>
        {/* 解决方案2: 点击时执行箭头函数, 箭头函数再执行内部的方法 */}
        <button onClick={() => this._chooseItem("睡觉")}>睡觉</button>
        <button onClick={() => this._chooseItem("打亮亮")}>打亮亮</button>
      </div>
    );
  }
}

回顾

React 作为三大框架之一: vue angular react

  • vue, angular
    • 属于一套思路: 在HTML中写 JS
    • {{}} v-html v-model ...
  • React
    • 在 JS 中 写 HTML

JSX语法:

  • 是一个语法糖写法: 需要babel工具编译才能执行
  • 在JS原生语法下: 函数封装特征无法 达到简化 DOM 操作的目的

组件: 组成页面的零件, 最大特征: 复用

  • 函数
    • 必须大驼峰的函数名: 为了区分普通函数
    • 必须继承父类, 才会有强大的功能

事件:

  • 事件写法: on事件名
  • 重点: 触发函数的 this 指向问题

思路: 在HTML中写 JS

  • {{}} v-html v-model ...
  • React
    • 在 JS 中 写 HTML

JSX语法:

  • 是一个语法糖写法: 需要babel工具编译才能执行
  • 在JS原生语法下: 函数封装特征无法 达到简化 DOM 操作的目的

组件: 组成页面的零件, 最大特征: 复用

  • 函数
    • 必须大驼峰的函数名: 为了区分普通函数
    • 必须继承父类, 才会有强大的功能

事件:

  • 事件写法: on事件名
  • 重点: 触发函数的 this 指向问题

上一篇:React 的setState


下一篇:LeetCode记录(1)——Array