文章目录
- 一、React是什么
- 二、React数据对比
- 三、React特点
- 3.1 技术特点
- 3.2 声明式编程
- 3.3 组件化开发
- 3.4 多平台适配
 
- 四、React开发依赖
- 4.1 React的开发依赖
- 4.2 Babel和React的关系
- 4.3 React的依赖引入
 
- 五、React初体验
- 5.1 Hello World
- 5.2 增加按钮,点击修改文本
- 5.3 组件化开发
- 5.5 组件化开发之数据依赖
- 5.5 组件化开发之事件绑定
- 5.6 版本16与18的小区别
- 5.7 案例:电影列表
- 5.8 案例:计数器
 
 
一、React是什么
- 相信每个做开发的人对它都或多或少有一些印象
- 我们来看一下官方对它的解释用于构建用户界面的 JavaScript 库
- 中文官网文档
  
  
目前对于前端开发来说,几乎很少直接使用原生的JavaScript来开发应用程序,而是选择一个JavaScript库(框架)。
- 在过去的很长时间内,jQuery是被使用最多的JavaScript库
- 在过去的一份调查中显示,全球前10,000个访问最高的网站中,有65%使用了jQuery,是当时最受欢迎的JavaScript库,但是,目前甚至已经处于淘汰的边缘了
二、React数据对比
而无论是国内外,最流行的其实是三大框架:Vue、React、Angular,如下:
 
 框架Google指数对比:
 
 NPM下载量对比:
 
 Github数据对比:
 
三、React特点
3.1 技术特点
React由Facebook来更新和维护,它是大量优秀程序员的思想结晶:
- React的流行不仅仅局限于普通开发工程师对它的认可;
- 大量流行的其他框架借鉴React的思想;
Vue.js框架设计之初,有很多的灵感来自Angular和React。
- 包括Vue3很多新的特性,也是借鉴和学习了React
- 比如React Hooks是开创性的新功能
- Vue Composition API学习了- React Hooks的思想
Flutter的很多灵感都来自React:
- 事实上Flutter中的Widget – Element – RenderObject
- 对应React的就是JSX – 虚拟DOM – 真实DOM
所以React可以说是前端的先驱者,它总是会引领整个前端的潮流。
3.2 声明式编程
- 声明式编程是目前整个大前端开发的模式:Vue、React、Flutter
- 允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面;
  
3.3 组件化开发
- 组件化开发页面目前前端的流行趋势,我们会将复杂的界面拆分成一个个小的组件;
- 如何合理的进行组件的划分和设计也是一个重点;
  
3.4 多平台适配
- 2013年,React发布之初主要是开发Web页面;
- 2015年,Facebook推出了ReactNative,用于开发移动端跨平台
- 2017年,Facebook推出ReactVR,用于开发虚拟现实Web应用程序

四、React开发依赖
4.1 React的开发依赖
开发React必须依赖三个库:
- react:包含- react所必须的核心代码
 -- react-dom:- react渲染在不同平台所需要的核心代码
- babel:将- jsx转换成- React代码的工具
第一次接触React会被它繁琐的依赖搞蒙,居然依赖这么多东西:
- 对于Vue来说,我们只是依赖一个vue.js文件即可,但是react居然要依赖三个包
- 其实呢,这三个库是各司其职的,目的就是让每一个库只单纯做自己的事情;
- 在React的0.14版本之前是没有react-dom这个概念的,所有功能都包含在react里;
为什么要进行拆分呢?原因就是react-native。
- react包中包含了- react web和- react-native所共同拥有的核心代码。
- react-dom针对- web和- native所完成的事情不同:
 ✓- web端:- react-dom会将- jsx最终渲染成真实的- DOM,显示在浏览器中
 ✓- native端:- react-dom会将- jsx最终渲染成原生的控件- (比如Android中的Button,iOS中的UIButton)
4.2 Babel和React的关系
Babel是什么呢?
- Babel又名- Babel.js
- 是目前前端使用非常广泛的编译器、转移器
- 比如当下很多浏览器并不支持ES6的语法,但是确实ES6的语法非常的简洁和方便,我们开发时希望使用它
- 那么编写源码时我们就可以使用ES6来编写,之后通过Babel工具,将ES6转成大多数浏览器都支持的ES5的语法
React和Babel的关系:
- 默认情况下开发React其实可以不使用babel
- 但是前提是我们自己使用 React.createElement来编写源代码,它编写的代码非常的繁琐和可读性差
- 那么我们就可以直接编写jsx(JavaScript XML)的语法,并且让babel帮助我们转换成React.createElement
4.3 React的依赖引入
所以,我们在编写React代码时,这三个依赖都是必不可少的。
那么,如何添加这三个依赖:
- 方式一:直接CDN引入
- 方式二:下载后,添加本地依赖
- 方式三:通过npm管理(后续脚手架再使用)
◼ 暂时我们直接通过CDN引入,来完成示例程序
 ps: 这里有一个crossorigin的属性,这个属性的目的是为了拿到跨域脚本的错误信息
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
五、React初体验
5.1 Hello World
在界面上通过React显示一个Hello World,代码如下:
<body>
  <div id="root"></div>
  <!-- 加载 React。-->
  <!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <script type="text/babel">
    // ReactDOM.render(<h2>Hello World</h2>, document.querySelector('.root'))
    const root = ReactDOM.createRoot(document.querySelector('#root'))
    root.render(<h2>Hello React18</h2>)
  </script>
</body>
- ReactDOM.createRoot函数:用于创建一个- React根,之后渲染的内容会包含在这个根中- 参数:将渲染的内容,挂载到哪一个HTML元素上,这里我们已经提定义一个id为app的div
 
- 参数:将渲染的内容,挂载到哪一个
- root.render函数: 
  - 参数:要渲染的根组件
 
- 可以通过{}语法来引入外部的变量或者表达式
- 这里我们编写React的script代码中,必须添加type="text/babel",作用是可以让babel解析jsx的语法。
5.2 增加按钮,点击修改文本
新增按钮,点击后修改message的值,代码如下:
<div id="root"></div>
<script type="text/babel">
  let message = 'hello world'
  const root = ReactDOM.createRoot(document.querySelector("#root"))
  function changeMessage(){
    message = 'hello react'
    root.render(
      <div>
        <h2>{message}</h2>
        <button onClick={changeMessage}>点我</button>
      </div>
    )
  }
  root.render(
    <div>
      <h2>{message}</h2>
      <button onClick={changeMessage}>点我</button>
    </div>
    )
</script>
5.3 组件化开发
整个逻辑其实可以看做一个整体,那么我们就可以将其封装成一个组件:
- 我们说过root.render参数是一个HTML元素或者一个组件
- 所以我们可以先将之前的业务逻辑封装到一个组件中,然后传入到 ReactDOM.render函数中的第一个参数
在React中,如何封装一个组件呢?这里我们暂时使用类的方式封装组件:
- 定义一个类(类名大写,组件的名称是必须大写的,小写会被认为是HTML元素),继承自React.Component
- 实现当前组件的render函数,render当中返回的jsx内容,就是之后React会帮助我们渲染的内容
  
5.5 组件化开发之数据依赖
在组件中的数据,我们可以分成两类:
- 参与界面更新的数据:当数据变量时,需要更新组件渲染的内容
- 不参与界面更新的数据:当数据变量时,不需要更新将组建渲染的内容;
参与界面更新的数据我们也可以称之为是参与数据流,这个数据是定义在当前对象的state中
- 我们可以通过在构造函数中this.state = {定义的数据}
- 当我们的数据发生变化时,我们可以调用this.setState来更新数据,并且通知Reac进行update操作
- 在进行update操作时,就会重新调用render函数,并且使用最新的数据,来渲染界面
  
5.5 组件化开发之事件绑定
事件绑定中的this===>在类中直接定义一个函数,并且将这个函数绑定到元素的onClick事件上,当前这个函数的this指向的是谁呢?
默认情况下是undefined
- 很奇怪,居然是undefined
- 因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象)
- 这次因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象;
- 那么在这里发生监听的时候,react在执行函数时并没有绑定this,默认情况下就是一个undefined
- 我们在绑定的函数中,可能想要使用当前对象,比如执行this.setState函数,就必须拿到当前对象的this
- 我们就需要在传入函数时,给这个函数直接绑定this
类似于下面的写法:
 
 当然也可以在组件的构造函数中对方法进行绑定,如下:
 
5.6 版本16与18的小区别
<script type="text/babel">
  // 编写React代码(jsx语法)
  // jsx语法 -> 普通的JavaScript代码 -> babel
  // 渲染Hello World
  // React18之前: ReactDOM.render
  ReactDOM.render(<h2>Hello World</h2>, document.querySelector("#root"))
  // React18之后:
  const root = ReactDOM.createRoot(document.querySelector("#root"))
  root.render(<h2>Hello World</h2>)
</script>
5.7 案例:电影列表
<body>
  <!-- 加载 React。-->
  <!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <div id="root"></div>
  <script type="text/babel">
    class AppMain extends React.Component {
      constructor() {
        super()
        this.state = {
          movies: ['大话西游', '功夫', '西游降魔', '赌圣']
        }
      }
      render() {
        return (
          <div>
            <h2>电影列表</h2>
            <ul>
              {this.state.movies.map(item => {
                return <li>{item}</li>
              })}
            </ul>
          </div>
        )
      }
    }
    const root = ReactDOM.createRoot(document.querySelector("#root"))
    root.render(
      <AppMain />
    )
  </script>
</body>
5.8 案例:计数器
<body>
  <!-- 加载 React。-->
  <!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <div id="root"></div>
  <script type="text/babel">
    class AppMain extends React.Component {
      constructor() {
        super()
        this.state = {
          count: 100
        }
        this.add = this.add.bind(this)
        this.sub = this.sub.bind(this)
      }
      add() {
        this.setState({
          count: this.state.count + 1
        })
      }
      sub() {
        this.setState({
          count: this.state.count - 1
        })
      }
      render() {
        let { count } = this.state
        return (
          <div>
            <h2>当前数值:{count}</h2>
            <button onClick={this.add}>点我+1</button>
            <button onClick={this.sub}>点我-1</button>
          </div>
        )
      }
    }
    const root = ReactDOM.createRoot(document.querySelector("#root"))
    root.render(
      <AppMain />
    )
  </script>
</body>












![特殊类设计[上]](https://img-blog.csdnimg.cn/05b237b85c404531b2e08ed1730fe02e.png)




![2023年中国儿童滑板车优点、市场规模及发展前景分析[图]](https://img-blog.csdnimg.cn/img_convert/711022110611124cabb58f9a4af42996.png)

