1801A React

一、初识React

课程目标

  1. React简介
  2. 脚手架
  3. hello world
  4. JSX语法

知识点

1.React简介

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站(https://www.instagram.com/)。做出来以后,发现这套东西很好用,就在2013年5月开源了(https://github.com/facebook/react)。由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

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

英文官方网站:https://reactjs.org/

目前的版本: 16.13.1

github star数:149k (vue是164k)

npm下载量对比:https://npmcharts.com/compare/react,vue

2.脚手架

create-react-app官网:https://github.com/facebook/create-react-app

npm 从5.2版开始,增加了 npx 命令。

npx 还能避免全局安装的模块。

npx 将create-react-app下载到一个临时目录,使用以后再删除。所以,以后再次执行上面的命令,会重新下载create-react-app。

每次使用的都是最新版本,脚手架使用的频率并不高,一个大项目使用一次就够了。

npx create-react-app my-app
cd my-app
npm start

3.hello world

类组件:

import React, { Component } from 'react'

export default class Home extends Component {
  render() {
    return (
      <div>
        hello world!
      </div>
    )
  }
}

函数组件:

import React from 'react'

const Home = () => {
  return (
    <div>
      hello world!
    </div>
  )
}

export default Home

4.JSX语法

React发明了JSX,利用HTML语法来创建虚拟DOM。

React的核心机制之一就是可以在内存中创建虚拟的DOM元素。以此来减少对实际DOM的操作从而提升性能。

JSX 即Javascript XML,它是对JavaScript 语法扩展。

我们建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。

在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。

HTML 语言直接写在 JavaScript 语言之中,这就是 JSX(JavaScript and XML) 的语法。JSX,是一种 JavaScript 的语法扩展,它允许 HTML 与 JavaScript 的混写。JSX是facebook为React框架开发的一套语法糖,语法糖又叫做糖衣语法,是指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用,它主要的目的是增加程序的可读性,从而减少程序代码错处的机会。JSX就是JS的一种语法糖,类似的还有CoffeeScript、TypeScript,最终它们都会被解析成JS才能被浏览器理解和执行,如果不解析浏览器是没有办法识别它们的,这也是所有语法糖略有不足的地方。

const element = <h1>Hello, world!</h1>;

上面这种看起来可能有些奇怪的标签语法既不是字符串也不是HTML,被称为 JSX,JSX带来的一大便利就是我们可以直接在JS里面写类DOM的结构,比我们用原生的JS去拼接字符串,然后再用正则替换等方式来渲染模板方便和简单太多了。推荐在 React 中使用 JSX 来描述用户界面。JSX 用来声明 React 当中的元素, 乍看起来可能比较像是模版语言,但事实上它完全是在 JavaScript 内部实现的。

你可以任意地在 JSX 当中使用 JavaScript 表达式,在 JSX 当中的表达式要包含在大括号里。例子如下:

const names = ['Jack', 'Tom', 'Alice'];
const element = (
  <div>
     { names.map(function (name) { return <div>Hello, {name}!</div>}) }
  </div>
);

在书写 JSX 的时候一般都会带上换行和缩进,这样可以增强代码的可读性。与此同时,推荐在 JSX 代码的外面扩上一个小括号,这样可以防止分号自动插入的bug。

上面我们声明了一个names数组,然后遍历names数组在前面加上Hello,生成了element数组。JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员。JSX 本身其实也是一种表达式,在编译之后,JSX 其实会被转化为普通的 JavaScript 对象。

授课思路

1801A React_第1张图片

案例作业

1.阅读官网
2.使用脚手架创建项目
3.编写hello world页面
4.预习加加减减

二、加加减减

课程目标

  1. VSCode插件
  2. 添加样式
  3. 加加减减
  4. JSX语法

知识点

1.VSCode插件

ES7 React/Redux/GraphQL/React-Native snippets

快捷方式:
创建类组件: rcc
创建函数数据:raface

2.添加样式

使用className,而不是class

import React from 'react'

const Home = () => {
  return (
    <div className="m-title">
      hello world!
      <span className="m-name"></span>
    </div>
  )
}

export default Home

想使用sass同学可以安装node-sass

yarn add node-sass

把样式文件改成scss就行了

.m-title{
  color: red;
  .m-name{
    color: lightblue;
  }
}

3.加加减减

constructor构造函数在组件创建时执行,super代表调用父类的构造函数,Component就是父类。

state是状态的意思,类似于vue的里的data。

修改state使用setState方法。

onClick是React合成事件。

import React, { Component } from 'react'

export default class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 0
    }
  }

  handleSub() {
    let { count } = this.state
    count--
    this.setState({
      count
    })
  }

  handleAdd() {
    let { count } = this.state
    count++
    this.setState({
      count
    })
  }

  render() {
    let { count } = this.state
    return (
      <div>
        <div>{count}</div>
        <button onClick={() => this.handleSub()}></button>
        <button onClick={() => this.handleAdd()}></button>
      </div>
    )
  }
}

1801A React_第2张图片

4.事件系统

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。

不会存在IE浏览器兼容性的问题。

在React底层,主要对合成事件做了两件事情:事件委派和自动绑定。

  1. 事件委派

React中并不是把事件处理函数绑定到当前DOM上,而是把所有的事件绑定到结构的最外层,使用统一的事件监听器。
这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。
组件挂载和卸载时,只是在统一事件监听器上插入删除一些对象。

  1. 自动绑定

在React组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前的组件。而且React会对这种引用缓存,以达到CPU和内存的最大优化。

vue里是使用@click绑定点击事件。

授课思路

1801A React_第3张图片

案例作业

1.上网阅读相关质料
2.制作加加减减
3.添加样式
4.预习列表渲染

三、列表渲染

课程目标

  1. map方法
  2. 列表渲染
  3. key
  4. 学习资料

知识点

1.map方法

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。

    let arr = [1, 2, 3]
    let arr2 = arr.map(item => item * 2)
    console.log(arr2)

2.列表渲染

在state里定义一个数组,包含id
把数组里的字段渲染到页面上
类似于vue里的v-for

import React, { Component } from 'react'

export default class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      list: [
        {
          id: 0,
          title: '武侠'
        },
        {
          id: 1,
          title: '都市'
        },
        {
          id: 2,
          title: '科幻'
        }
      ]
    }
  }
  render() {
    let { list } = this.state

    let listDom = list.map(item => (
      <div key={item.id}>{item.title}</div>
    ))

    return (
      <div>
        {listDom}
      </div>
    )
  }
}

1801A React_第4张图片

3.key

key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用数据中的 id 来作为元素的 key。

这个 key 必须是每个元素唯一的标识。key可以在DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化,提高渲染性能。所以需要给数组每一个元素增加一个唯一的标识。
一般可以将后台返回的ID作为key值,因为后台返回的ID都是唯一的。

4.学习资料

官网列表渲染:
https://react.docschina.org/docs/lists-and-keys.html

菜鸟教程列表渲染:
https://www.runoob.com/react/react-lists-and-keys.html

授课思路

1801A React_第5张图片

案例作业

1.上网阅读相关质料
2.列表渲染
3.预习条件渲染

四、条件渲染

课程目标

  1. 条件渲染dom
  2. 条件渲染样式
  3. key
  4. 学习资料

知识点

1.条件渲染dom

dom的显示和隐藏:hello world!的显示与隐藏。
文案的切换:按钮文案的变化。
属性的切换:控制密码的显示隐藏。
在vue里使用v-if v-show。

import React, { Component } from 'react'

export default class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      visible: false
    }
  }

  handleVisible() {
    let { visible } = this.state
    this.setState({
      visible: !visible
    })
  }

  render() {
    let { visible } = this.state
    return (
      <div>
        <input type={ visible ? "text" : "password" } ></input>
        <button onClick={() => this.handleVisible()}>{ visible ? '隐藏' : '显示' }</button>
        {
          visible ? <div>hello world!</div> : null
        }
      </div>
    )
  }
}

1801A React_第6张图片

2.条件渲染样式

根据状态控制样式:tab切换的高亮显示。

import React, { Component } from 'react'

export default class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      list: [
        {
          id: 0,
          title: '武侠'
        },
        {
          id: 1,
          title: '都市'
        },
        {
          id: 2,
          title: '科幻'
        }
      ],
      currentId: 0
    }
  }

  handleNav(currentId) {
    this.setState({
      currentId
    })
  }

  render() {
    let { list, currentId } = this.state

    let listDom = list.map(item => (
      <div key={item.id} className={ `m-nav-item ${currentId === item.id ? 'active' : ''}` } onClick={() => this.handleNav(item.id)}>{item.title}</div>
    ))

    return (
      <div>
        {listDom}
      </div>
    )
  }
}
.m-nav-item{height: 40px;line-height: 40px;border-bottom: 1px solid #ddd;text-align: center;}
.m-nav-item.active{background: lightblue;}

1801A React_第7张图片

3.对话框

控制dom的显示和隐藏:dialog对话框。

div水平垂直居中。

import React, { Component } from 'react'

export default class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {
      visible: false
    }
  }

  handleVisible() {
    let { visible } = this.state
    this.setState({
      visible: !visible
    })
  }

  handleClose() {
    this.setState({
      visible: false
    })
  }

  render() {
    let { visible } = this.state
    return (
      <div>
        <button onClick={() => this.handleVisible()}>{ visible ? '隐藏' : '显示' }</button>
        {
          visible ? 
          <div className="m-dialog-wrap">
            <div className="m-dialog">
              <div className="m-dialog-header">
                <div className="m-dialog-title">添加</div>
                <div className="m-dialog-close" onClick={() => this.handleClose()}>X</div>
              </div>
            </div>
          </div> : null
        }
      </div>
    )
  }
}

.m-dialog-wrap{display: flex; position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.5);}
.m-dialog{margin: auto;min-width: 300px;min-height: 240px;background: #fff;border-radius: 10px;}
.m-dialog-header{display: flex;height: 40px;line-height: 40px;border-bottom: 1px solid #ddd;}
.m-dialog-title{flex: 1;padding: 0 0 0 10px;}
.m-dialog-close{width: 40px;text-align: center;cursor: pointer;}

1801A React_第8张图片

4.学习资料

官网条件渲染:
https://react.docschina.org/docs/conditional-rendering.html

菜鸟教程条件渲染:
https://www.runoob.com/react/react-conditional-rendering.html

授课思路

1801A React_第9张图片

案例作业

1.上网阅读相关质料
2.制作对话框
3.预习受控组件

五、受控组件

课程目标

  1. 什么是受控组件
  2. 文本框受控组件
  3. 如何获取受控组件的值
  4. 学习资料

知识点

1.什么是受控组件

在 HTML 中,表单元素(如