React入门篇 | 青训营笔记

88 阅读5分钟

React 是 Facebook 在2013年开源的用于构建用户界面的 JavaScript 库。React 不是一个框架 —— 它的应用甚至不局限于 Web 开发,它可以与其他库一起使用以渲染到特定环境。例如,React Native 可用于构建移动应用程序;React 360 可用于构建虚拟现实应用程序……

为了构建 Web 应用,开发人员将 React 与 ReactDOM 结合使用。React 和 ReactDOM 通常被与其他真正的 Web 开发框架相提并论,并用于解决相同的问题。当我们将 React 称为“框架”时,就是在进行口语化的理解。React的特点包括:

  • 声明式(即以结果为导向的)
  • 组件化
  • 跨平台编写

一、三个重要的API

首先,我们通过引入外部JS脚本的方式来简单体会一下使用React开发Web项目,以下是一个简单的HelloWord程序。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Word</title>
    <!-- 引入React核心库 -->
    <script src="./script/react.development.js"></script>
    <!-- 引入React的DOM库 -->
    <script src="./script/react-dom.development.js"></script>
</head>
<body>
    <div id="root"></div>
    <script>
        // 创建一个React元素
        const div = React.createElement('div', {
            id: 'content',
            className: 'hello',
            onClick: () => {
                alert('hello word!')
            }
        }, 'Hello Word!')
        // 获取根元素
        const root = ReactDOM.createRoot(document.getElementById('root'));
        // 将元素在根元素中显示
        root.render(div)

        // ******************************
        //原生方法
        // 通过DOM向页面中添加一个div
        // 创建一个div
        // const div = document.createElement('div'); // 创建一个dom元素
        // // 向div中设置内容
        // div.innerText = '我是一个div';
        // // 获取root
        // const root = document.getElementById('root');
        // // 将div添加到页面中
        // root.appendChild(div);

    </script>
</body>
</html>

在上述代码中,有三个非常重要的API:

  1. React.createElement(type, [props], [...children]) 用来创建React元素, 注意React元素创建后是无法修改的,而是通过生成新的React元素去替换原来的React元素来达到修改的目的。
  2. ReactDOM.createRoot.createRoot(container[, options]) 用来创建React的根容器,容器用来放置 React 元素。
  3. root.render(element) 当首次调用时,容器节点里的所有DOM元素都会被替换,后续的调用则会使用React的DOM差分算法(DOM Diff Algorithm)进行高效的更新。

二、一些基础概念

1.JSX

JSX 是 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以它既具备了 Javascript 的灵活性,同时又兼具 html 的语义化和直观性。在 React 中,JSX 可以生成 React “元素”。JSX更像一种模板,类似于Vue中的 template。以下为一段基于JSX实现渲染列表的代码,是不是很方便?我们不再需要写很多很多的React.createElement()了~

//渲染列表
let data = ['孙悟空', '猪八戒', '唐僧']
let ul = <ul>{data.map(item => <li key={item}>{item}</li>)}</ul>

let root = ReactDOM.createRoot(document.getElementById('root'))
root.render(ul)

事实上,JSX就是一种语法糖,在内部 Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用,创建对应的 DOM 对象,转换后的代码如下所示:

var data = ['孙悟空', '猪八戒', '唐僧'];
var ul = /*#__PURE__*/React.createElement("ul", null, data.map(function (item) {
  return /*#__PURE__*/React.createElement("li", {
    key: item
  }, item);
}));
var root = ReactDOM.createRoot(document.getElementById('root'));
root.render(ul);

一些关于JSX的注意事项:

  1. JSX不是字符串,不要加引号
  2. JSX中html标签应该小写,React组件应该大写开头
  3. JSX的标签必须正确结束(自结束标签必须写/)
  4. 在JSX中可以使用{}嵌入表达式,如果表达式是空值、布尔值、undefined,将不会显示
  5. 在JSX中,属性可以直接在标签中设置,class需要使用className代替,style中必须使用对象设置,如:style={{background:'red'}}

2.虚拟DOM

在React我们操作的元素被称为React元素,并不是真正的原生DOM元素,React通过虚拟DOM 将React元素 和 原生DOM,进行映射,虽然操作的React元素,但是这些操作最终都会在真实DOM中体现出来。那么什么是虚拟DOM呢?虚拟DOM可以看做一棵模拟了DOM树的JavaScript对象树。比如:

var element = {
    element: 'ul',
    props: {
        id:"list"
    },
    children: [
    { element: 'li', props: { id:"first" }, children: ['这是第一个List元素'] },
    { element: 'li', props: { id:"second" }, children: ['这是第二个List元素'] }
    ]
}

虚拟DOM存在的意义在于:

  • 降低API复杂度,即以原生的方式操作DOM, API多且复杂在实际开发中多有不便
  • 解决兼容问题,即以原生的方式操作DOM, 需要考虑不同浏览器不同版本间的兼容性问题
  • 提升性能,即通过Diff算法对比新旧虚拟DOM, 能减少DOM的不必要操作

3.组件

组件是应用程序根据UI结构划分的不同功能的代码的集合,其主要特点可概括为:独立、可复用、可组合。 React组件有两种创建方式,即 Class组件 和 函数式组件。

使用 ES6 的 class 创建的组件,叫做类(Class)组件, 示例如下:

const title = <h1>Class组件</h1>

// 1. 定义一个类组件
class  MyDiv  extends  React.Component {
  render () {
    return <div>这是一个div</div>
  }
}

// 2.使用组件,单标签和双标签模式使用都可以
const  content = (
  <div>
           {title}
          {<MyDiv />}
  </div>
)

// 渲染
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(content)

Class组件定义的注意事项:

  1. 类名必须以大写字母开头
  2. extends是一个关键字,用来实现类之间的继承。类组件应该继承 React.Component 父类,从而使用父类中提供的方法或属性。
  3. 类组件必须提供 render 方法,render 方法必须有返回值,表示该组件的 UI 结构。render会在组件创建时执行一次

使用 JS 的函数(或箭头函数)创建的组件,叫做函数式组件, 示例如下:

const title = <h1>react中的函数式组件</h1>

// 1.使用箭头函数定义一个函数式组件
const MyDiv = () => {
  return <div>给我一个div</div>
}

// 2.使用普通函数定义一个函数式组件
function Button() {
  return <button></button>
}

// 3.使用组件,单标签和双标签模式使用都可以
const content = (
  <div>
    {title}
    {<MyDiv />}
    {<Button />}
  </div>
)

// 渲染
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(content)

函数式的注意事项:

  1. 函数名首字符大写,组件名称须以大写字母开头,React 据此区分 组件 和 普通的 HTML
  2. 必须有返回值,表示该组件的 UI 结构;如果不需要渲染任何内容,则返回 null