react框架介绍

820 阅读12分钟

react简介

React用于构建用户界面的javascript库, 官方提供核心的一些内容,需要靠周边生态来支撑他的运行。

React-起源于facebook内部项目。

React一般被用来作为MVC中的V层,它不依赖其他任何的库

React的思想非常独特,性能出众

React的语法是jsx,通过使用这种语法,可以在react代码中直接混合使用js和html来编写代码

react思想:

  1. 解决UI层面的设计。
  2. React有两个分支,一个分支WEB端(React-DOM)、一个分支移动端(React-Native)。

官方:

reactjs.org

中文网:

react.docschina.org

react特点

1

  1. 组件化开发思想:SPA,组件需求,JSX
  2. 社区完善,适合于大型的web应用开发
  3. facebook团队维护,版本稳定,持续更新
  4. 开发适用于多个场景
  5. 虚拟DOM
  6. DOM diff算法

react高效的原因就是虚拟dom和dom diff算法

Vue 和 React 的区别是什么?

  1. Vue 是基于 MVVM 架构的前端框架,React 是基于 MVC 架构的前端库;

  2. Vue 支持双向数据绑定,React 不支持双向数据绑定;

  3. Vue 是通过响应式的方式来侦听数据变化并更新组件,React 中是通过调用 setState 方法来修改数据更新组件;

  4. Vue 官方有配套的状态机和路由,React 官方没有,需要使用第三方的路由和状态机插件;

  5. Vue 主要采用的是模版语法来编写组件,而 React 主要采用的是 JSX 的语法来编写组件;

  6. Vue 封装得更深,上手入门更容易,React 封装得较少,上手入门较难,但使用更灵活;

核心模板的组成

React当成库来使用,你们只需要在html项目中引入react.js可以开始开发。

1、首先我们去React官网reactjs.org/下载开发所需要的文件。…

2、初学React的小伙伴们,咱们需要下载两个JS文件。

分别是react.development.js与react-dom.development.js。

  • react.development.js:React的核心库,用于创建UI

  • react-dom.development.js:提供与DOM相关的功能。用于将创建的UI渲染到浏览器中。

注: 为什么要把 React 和 ReactDOM 分开呢?

React 在v0.14以前是沒有 ReactDOM 的,全部功能都包含在 React 里, 因为有了 ReactNative,才分开。React 只包含了 Web 和 Mobile 通用的核心部分,负责 Dom 操作的分到 ReactDOM 中,负责 Mobile 的包含在 ReactNative 中。

ReactDom是React的一部分。ReactDOM是React和DOM之间的粘合剂。

创建虚拟dom

需求: 利用虚拟dom渲染的方式新建dom节点,并显示'hello react'

通过React.createElement的方式


<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    
</head>
<body>
    <div id="app"></div>
    <script>
        const str = '你好,世界';
        // 通过React.createElement 创建虚拟dom
        // React.createElement(type, props, children)
        const vDom = React.createElement('div',{
                className:'test',
                style:{color:'red'}
            },
            str);
        //浏览器解析出来: <div className="test">hello react</div> 

        // 把虚拟dom转化成真实的dom,
        // ReactDOM.render 是 React18版本之前 的最基本方法,用于将虚拟dom转为 HTML 语言,
        // 并插入指定的 DOM 节点。
        // ReactDOM.render(vDom,document.getElementById("app"))
       
        const root = ReactDOM.createRoot(document.getElementById("app"))
        // root.render 将虚拟dom转化为真实dom
        root.render(vDom)
    </script>
</body>
</html>
    

const root = ReactDOM.createRoot 创建根节点;

root.render 方法 把虚拟dom转换为真实dom 并渲染在模板中

在 React 中,"root" 是一个指向顶层数据结构的指针,React 用它来跟踪要渲染的树。

涉及知识点:

  1. 为啥要引入react和reactDom 2个包?

  2. 如何通过react创建 虚拟dom?

  3. 如何使用ReactDOM将模板转化为html语言?

通过jsx语法的方式

Babel:可以将ES6代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。

Babel 内嵌了对 JSX 的支持

JSX=JavaScript and XML(HTML)

jsx的特点:

  1. 开发代码更简洁
  2. 性能更好,
  3. 执行更快,编译代码的时候就会进行代码优化
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

已经要记得在script里加上type="text/babel" 来对jsx语法的支持

 <script type="text/babel">
 // 通过jsx创建虚拟dom
  const str = 'hello react'
  var domStr = <div className="test" style={{color:'red'}}>{str}</div>;
  // const vDom = <h1 id="myId">hello react</h1>
  // 把虚拟dom转化成真实的dom
  ReactDOM.render(domStr,document.getElementById("app"))
</script>
  1. 你需要引入一个babel包, 内置了jsx的语法支持, 可以让你在模板中写html和js
  2. 在script标签要引入 type="text/babel"
  3. jsx中模板渲染通过{}
  4. 样式:可以使用内部style定义样式 , 也可以使用外部样式 , 然后通过className来使用

注意:style中你看到2个{{}}, 外面一层代表 模板渲染的语法, 里面一层代表style是一个对象的形式,而且属性都是以驼峰式命名的, 比如background-color - > backgroundColor

创建虚拟dom的两种方式

  • React.createElement

  • jsx

react中样式处理

在JSX中使用css样式,有两种方案

  1. 行内样式(内联样式)

    直接在标签上面添加css样式

    var domStr = <div className="test" style={{color:'red'}}>{str}</div>;
    

    如果你要标签上面直接写style,必须动态绑定样式.css样式有多个,里面值也是一个对象, 所以你看起来是双括号{{}}

    JSX已经将CSS代码重新封装了一次.样式名需要是驼峰式

    backgroundColor->>background-color

    只要css代码原来有连字符,都是驼峰命名

  2. 外部样式

将样式代码写到外部去,引入进来使用

class---JSX要求你必须className

jsx语法逻辑处理

练习:jsx逻辑处理及运算

var a1 = true;
var price = 1000;
var divD = <div className="a">{a1?'北京':'上海'}  {price * 10}</div>
ReactDOM.render(
   divD,
   document.getElementById("app")
);

总结:

  1. 三目运算符来进行逻辑处理

    <div>{state?"开启":"关闭"}</div>
    
  2. 运算符处理,支持加减乘除运算符

    <div>{price * 10}</div>
    <div>{price / 10}</div>
    <div>{price > 10}</div>
    <div>{user && user.name}</div>
    <div>{show || show1}</div>
    

jsx数据动态渲染

实践需求:

var names = ['苹果','香蕉','桃子'];

利用jsx的语法把数组names 解析成列表进行渲染

列表结构<ul><li>香蕉</li></ul>

<div id="app"></div>
    <script type="text/babel">
        const arr = [{
            title:'苹果',
            price:10
        },{
            title:'西瓜',
            price:20
        }]

        var arrList = arr.map((item,index)=>{
            return <li key={index}>{item.title}  -- {item.price}</li>
        })
        console.log(arrList);
        const vDom = <ul>
                {arrList}
                </ul>
     const root = ReactDOM.createRoot(document.getElementById('app'))
        // 把虚拟dom转换为真实dom 并渲染在模板中
        root.render(vDom)
    </script>

总结:

  1. React提供JSX进行动态遍历的时候,实际上就是通过map拼接成我们想要的数组形式

    {list.map(item => {})}---->[<li></li>,<li></li>]
    
    

    JSX模板是可以渲染数组,但是里面内容不能是对象

  2. 遍历过程中也需要加上key,必须唯一

  3. 数据渲染以后都是页面中进行遍历,这样数据一旦发生变化,页面自动更新

类的定义和继承回顾

  // 类的名字第一个字母大写
        class People {
            static category = '人类'  // 相当于是一个全局变量, 访问是 People.category
            // 构造函数, 构造器
            constructor(name,age){
                this.username = name;
                this.age = age
            }
            say(){
                console.log(this.username);
            }
            run(){
                this.say()
            }
        }
        // 访问静态属性
        // console.log(People.category);
        // var p1 = new People('xiaohua',20);
        // console.log(p1);
        // p1.say()

        // 定义子类
        class Teacher extends People {
            constructor(username,age,school){
                super(username,age);  // 必须有super关键字
                this.school = school; // 定义自己的属性
            }
            walk(){
                console.log(this.school);
                console.log(this.username+'走路');
            }
        }
        var t1 = new Teacher('xiaobai',30,'武汉')
        t1.walk();

组件的概念

使用组件的方式进行编程,可以提高开发效率,提高组件的复用性、提高代码的可维护性和可扩展性

React定义组件的方式有两种

类组件:React16.8版本之前几乎React使用的都是类组件

函数组件:React16.8之后,函数式组件使用的越来越多

组件的定义的两种方式

定义类组件

类组件:是指通过ES6类来定义的组件称为类组件,React中定义类组件有如下约定

  • 类组件首字母大写

  • 类组件必须要继承React.Component父类,这个父类中的相关方法和属性都能被继承

  • 类组件中必须要有一个render方法

  • 这个render必须要有返回值,返回值的内容就是这个类组件的结构(jsx)

class Hello extends React.Component {
            // constructor(){
            // 组件内部数据可以定义在构造器里面
            //     super();
            //     this.state =  {
            //             name:'alice'
            //        }
            // }
            // 简写
            state = {
                name:'alice'
            }
            render() {
                // console.log(this);
                return <div>{this.state.name}</div>
            }
        }

类组件和函数式组件

  • 注意
    1. 组件名字一定要大写
    2. 虚拟dom只能有一个根标签, 必须有结束标签
    3. 必须有一个render方法, render方法里必须有一个return返回值
    4. 定义组件内部数据 必须要使用state
    5. 在模板中访问组件内部数据的时候, 要使用this (组件的实例化对象) this.state.属性名
  • render渲染组件的基本流程
    • react内部会创建组件的实例对象

    • 得到包含虚拟dom并且解析为真实的dom

    • 插入指定的页面元素里面

react 16.8版本之前 类组件是比较流行的, 因为类组件是有状态的, 你可以访问this,函数组件没有this, 所以用的很少。 但是随着发展, 目前已经到了版本18了, react官方推出了hooks,让函数组件功能变得强大起来, 目前也开始流行了

类组件的事件处理

vue中通过什么绑定事件处理函数?v-on指令来实现绑定,可以通过他的简写@事件类型方式来绑定事件的

在React中通过onClick属性来实现单击事件的绑定的,常见的写法

1.直接在标签中通过onClick={()=>{}}来实现事件的绑定

2.在标签中通过onClick={this.类中的普通成员方法}来进行绑定

3.在标签中通过onClick={this.类中的箭头函数}来进行绑定

4.在标签中通过onClick={()=>{this.函数名称()}}

建议使用箭头函数写法代替普通方法


 <div id="app"></div>
    <script type="text/babel">
        // 给予react基类组件定义一个react类组件
        class Hello extends React.Component {
            // 构造器
            constructor(props){
                super(props);
                this.state = {name:'hong'}
            }
            sayHello(lang){
                console.log('说话- hello');
                this.setState({
                    name:lang
                })
            }
            // 推荐
            runFun=(ev)=>{
                console.log('跑步'); 
             }

            // render函数返回组件的页面结构
            render(){
                console.log('我渲染了');
                return <div>
                    <p>你好啊</p>
                    <p>我的名字:{this.state.name}</p>
                     { /* 1. 箭头函数传参 */ }
                    <button onClick= {()=>this.sayHello('中文')}>点击我</button>
                    { /* 2. bind函数传参 , 改变作用于 */ }
                    <button onClick= {this.sayHello.bind(this,'中文')}>点击我</button>

                    { /* 3. 箭头函数定义 不传参, 通过data-方式传参, 跟微信小程序传参一样 */  }
                    <button tag="1" data-kind='2' onClick={this.runFun}>跑步传参</button>

                  {
                   /*  对比推荐:
                    在定义函数的时候使用箭头函数定义, 采用data-的方式传参,调用的时候采用
                    箭头函数定义 不传参 使用 */
                  }
                    </div>
            }
        }
        ReactDOM.render(<Hello/>, document.getElementById('app'))
    </script>

总结:

react组件的render函数何时调用

​ 1.第一次初始化的时候

​ 2.页面数据更新的时候

​ 3.强制更新forceUpdate的时候

render渲染组件的基本流程

  • react内部会创建组件的实例对象
  • 得到包含虚拟dom并且解析为真实的dom
  • 插入指定的页面元素里面

类组件的state

vue框架和React框架最大的一个好处就是不需要开发人员去操作DOM,只要大家操作了数据,自动DOM元素会发生改变,这种操作称为响应式

在vue中响应式数据主要来自两个部分

​ 组件内部响应式数据是定义在data选项

​ 来自子组件外部通过props来定义的

在React中也是一样,如果要定义响应式数据,组件内部的数据是定义在组件的state中,组件外部的数据是定义在props中

1、有状态组件和无状态组件

类组件是有状态组件:因为一个组件的状态是存放在类的实例上,state,props都是存在this上,所以类组件被称为有状态组件

函数组件是无状态组件:函数组件都没有this,函数不能存放状态

类组件比较强大,函数组件比较单一,类组件可以完成复杂的功能,但是函数组件是简单的组件

在React16.8版本之后引入hooks可以让函数组件也能操作状态

总结:React16.8之前函数组件是无状态组件,几乎很少使用

2、state的基本使用

第一步:定义数据,可以在构造函数内部,也可以在构造函数外部

第二步:获取数据,在使用数据的时候为了提高读取性能,最好使用解构赋值方式

第三部:修改数据的时候一定要使用setState({})来修改数据,这个方法是一个异步方法

第一步:定义数据

class Counter extends React.Component{
    //简化语法
    state={
       count:0
    }
    render(){
        return (
            <div>
                <h2>计数器</h2>
            </div>
        )
    }
}
export default Counter;

第2步、获取数据

通过this.state获取数据

class Counter extends React.Component{
    constructor(){
        super();
        this.state={
            count:0
        }
    }
    render(){
        return (
            <div>
                <h2>计数器</h2>
                <span>{this.state.count}</span>
             </div>
        )
    }
}
export default Counter;

在使用数据的时候,最好使用解构赋值的方式,这样能够提高性能

import React, { Component } from 'react'
 
export default class Counter extends Component {
    state = {
        num: 0
    }
    constructor() {
        super()
    }
    render() {
        const { num } = this.state;
        return (
            <div>
                <h1>计数器</h1>
                <span>{num}</span>
            </div>
        )
    }
}

第3步、修改数据

状态是可以改变的

​ 语法:this.setState({要修改的数据})

注意:不要直接修改state中的数据,这样是错误的

​ setState()作用:1.修改state 2.更新UI

import React, { Component } from 'react'
 
export default class Counter extends Component {
    state = {
        num: 0
    }
    constructor() {
        super()
    }
    render() {
        const { num } = this.state;
        return (
            <div>
                <h1>计数器</h1>
                <span>{num}</span>
                <button onClick={() => {
                    this.setState({
                        num: this.state.num + 1
                    })
                }}>+1</button>
            </div>
        )
    }
}

3、类组件的props属性

props的默认值

React的props的默认值设置有两种方法

  • 类名.defaultProps={key:value}

    export default class UserInfo extends React.Component{}
    UserInfo.defaultProps={
      title:'暂无标题',
      name:'暂无名称'
      }
    
  • static defaultProps={key:value}(推荐)

    export default class UserInfo extends React.Component{
        static defaultProps={
            title:'暂无标题',
            name:'暂无名称'
         }
    }
    

    props的只读性

通过props传递进来的基本类型,组件内部不能直接更改

实践作业-简单切换

image-20230224143024632

需求:

  1. 利用类组件实现一个简单tab切换, 内容相应改变
  2. 新闻按钮激活时, 内容显示新闻内容,关于我们按钮激活时 内容显示关于我们的内容
  3. 用一个组件实现即可,新闻内容和 关于我们无需另外写组件

涉及知识点巩固:

  1. 类组件的使用
  2. 动态渲染变量{}的使用
  3. jsx语法的使用
  4. onClick事件绑定以及this作用域的使用
  5. 组件命名首字母大写

代码演示:

<script src="lib/react.development.js"></script>
    <script src="lib/react-dom.development.js"></script>
    <script type="text/javascript" src="lib/babel.min.js"></script>
    <style>
      ul, li { list-style: none;}
      .menu-list { display: flex;}
      .menu-list li{ margin-right: 20px; cursor: pointer; }
      .active {
        color: #f60;
      }
    </style>
<body>
    <div id="my"></div>
    <script type="text/babel">
        /*组件*/
        /*定义标题*/
        class TabList extends React.Component{
          constructor() {
             //关键字 ,父类/子类继承的一种方式
            super();      
            this.state = {  
              flag:1
            }   
          }; 
          btnSwitchChange(type){
            this.setState({
              flag:type
            })
          };
          render(){
            var flag = this.state.flag;
            return (
              <div>
                <ul className="menu-list">
                  <li className={flag==1 ? 'active':''} onClick={()=>this.btnSwitchChange(1)}>新闻</li>
                  <li className={flag==2 ? 'active':''} onClick={()=>this.btnSwitchChange(2)}>关于我们</li>
                </ul>
                <div>
                  {flag==1 ? <p>新闻内容</p> : <p>关于我们内容</p>}
                </div>
              </div>
            )
          }
        };
        ReactDOM.render(
          <TabList />,
          document.getElementById("my")
        );
    </script>
  </body>

实践作业tab切换

进阶需求:

  1. 新增新闻组件 和关于我们组件
  2. 点击新闻按钮, 显示新闻组件里的内容
  3. 点击关于我们按钮, 显示关于我们组件里的内容

image-20230224143727479

知识点:

巩固类组件的使用规范

实践作业-todo列表

作业:

利用类组件完成一个todolist

  1. 可以添加一条任务,添加完毕清空输入框
  2. 可以删除数据

image-20230224172825108

代码演示:

 <div id="app"></div>
    <script type="text/babel">
        class TodoList extends React.Component {
            state = {
                currentVal:'',
                todoList:[{
                    name:'画画',
                    isFinshed:false
                }]
            }
            updateValue=(ev)=>{
                const value = ev.target.value;
                this.setState({
                    currentVal:value
                })
            }
            addTask=()=>{
                let todos = this.state.todoList;
                if(!this.state.currentVal) return;
                todos.push({
                    name:this.state.currentVal,
                    isFinshed:false
                })
                this.setState({
                    todoList:todos
                })
                //直接操作dom
                var inputDom = this.refs.input;
                inputDom.value =''
                
            }

            deleteTodo=(index)=>{
                console.log(this);
                this.state.todoList.splice(index,1);
                this.setState({
                    todoList:this.state.todoList
                })
            }
            render(){
                const {currentVal,todoList} = this.state;
                return (
                    <div>
                        <input type="text" onChange={this.updateValue} ref="input" />  
                        <button onClick={this.addTask}>添加</button>  <br />
                        <ul>
                            {todoList.map((item,index)=>{
                                return <li key={index}>{item.name}   ---    {item.isFinshed ? '完成' :'未完成'}  
                                    <button onClick={()=>this.deleteTodo(index)}>删除</button>   </li>
                            })}
                        </ul>

                    </div>
                )
            }
        }

        const root = ReactDOM.createRoot(app)
        root.render(<TodoList /> )
    </script>

然后在项目中把封装这个todolist

第一步: 以一个组件为整体封装成TodoList.jsx

第二步:拆分成TodoHeader.jsx 和 TodoItem.jsx列表 , TodoListLink.jsx作为主要容器

准备工作

  1. 必须安装nodejs 注意:安装nodejs稳定版本

  2. 用yarn替代npm

  3. reactjs.org/docs/create…

yarn 包管理器

Yarn是facebook发布的一款取代npm的包管理工具, 类似npm的包管理工具, 参考官方文档yarn.bootcss.com/

但是比npm更快速,可以离线缓存,在下一次安装这个包时,甚至不需要有互联网连接,因为包是从磁盘离线安装的

特点:

  1. 速度超快。 Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。

  2. 超级安全。 在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。

  3. 超级可靠。 使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。

全局安装:

使用 npm 全局安装 yarn:

npm install yarn -g

查看版本

要检查电脑中是否有安装 yarn,可以通过以下命令来查看 yarn 的版本

yarn --version

设置镜像

yarn config set registry http://registry.npm.taobao.org/
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass

查看配置: yarn config list // 显示所有配置项

常用命令

项目初始化, 用于在项目中生成package.json文件

yarn init -y

下载依赖包

yarn add 包名称
yarn add 包名称@版本号
# 局部安装开发环境的依赖包(上线后不需要)
yarn add 包名称 --dev

删除依赖包

yarn remove 包名称

根据pageage.json下载项目所需依赖包

yarn 或者  yarn install

全局操作

# 全局下载依赖包
yarn global add 包名称
# 删除全局的指定依赖包
yarn global remove 包名称