React class、函数组件

4/9/2019 reactclass组件函数组件

# 组件

类组件有react全部的特性,比如this,state,生命周期等 函数组件没有this,没有生命周期,但是执行快,不占内存,用于封装ui组件

# 类的概念

  • 类:es6 -- class
  • class的语法、使用: 声明一个类:class(关键字) + 类名 + 花括号
// class
class App {

}
  • 使用:new ClassName()

  • 类是什么?

答:模板,模块,模型,它本身不具有任何的功能,只是当我们实例化后,传入不同的参数,来进行一系列的操作 (就像模具)。

  • class类的概念,在前端里是最近出现的,属于 es6 语法,所以需要转码,实际上,类的概念来自于后端,
  • 前端里的类实际上不太标准,严格上来说:继承,是子类继承父类。但是前端里的类,父类也可以获取到子类的属性和方法,这是和标准的类概念的区别。基于 prototype 原型对象的查找就是一个链条式查找。

# react 里 class 组件的使用

classes6里对于class类名是有规范要求的,首先字母必须大写(react中自定义组件首先字母也要大写).

# class组件和函数组件的区别

  1. react里的class组件中,DOM 片段必须放在一个render的函数中

以下是class组件(DOM片段在render函数内部)

// class组件
class App {
    render() {
        return (
            <div>
                我是一个class组件
            </div>
        )
    }
}

以下是函数组件(DOM片段直接写在return()内)

// 函数组件
function Dome() {
    return (
        <div>
            我是函数组件
        </div>
    )
}

# class组件

  • react 里类不能直接用,需要继承extends

  • 格式: class + 类名 + extends + 基类 + {}

  • 继承的关键字 【前面是组件名】extends【继承=>】 React.Component 【基础的类/基类】

class Counter extends React.Component {
    constructor() {
        super()
    }
    render() {
        return <>
            <div></div>
        </>
    }
}
// 以上代码的意思就是:Counter类 继承自基类 React.Component
  • class组件里包含了所有的react特性:

函数组件中只有一个props属性,而在class 组件里有生命周期、捕获异常、容错边界、优化渲染等

// 函数组件的属性
function Son(props) {
    return (
        <div>
            我是函数组件
        </div>
    )
}

注:

类组件的props属性和函数组件里的props属性一模一样,就是在调用的时候classprops需要用this点出来

  • 实例:
// Son.jsx内容
import React from 'react'
export default class Son extends React.Component {
    // export default 的意思是默认导出 Son 组件
    render() {
        return (
            <div className={this.props.myclass}>
                <h2> 我是子组件</h2>
                {this.props.name}
            </div>
        )
    }
}
// index.jsx内容
import React from 'react'
import Son from './Son'
class App extends React.Component {
    render() {
        return (
            <div>
                我是一个class组件中
                <Son name="123" myclass='son-box' />
            </div>
        )
    }
}
export default App;

class里面所有的属性和方法都要用this,.出来

class Counter extends React.Component {
    constructor() {
        super()
        // this.
        this.state = { number: 1 }
    }
    add() {
        // 事件
        this.setState((prevState) => ({
            number: prevState.number + 1
        }))
        // prevState表示的是上一次的状态
    }
    render() {
        return <>
            <div>{this.state.number}</div>
            <button onClick={() => this.add()}>点击加1</button>
        </>
    }
}

# state 状态的基础理解

state 只有类组件有(函数组件用Hooks->useState),以下是state状态的介绍:

  • stateporps的区别

    • state状态:是组件自身的数据存储,它用来控制组件自己的变化

    • props属性:是父级传过来的数据,组件自身是不能操作修改 props 的

  • state必须是一个对象,react是单项数据流,并且数据是单向监听,修改的时候我们要用react自带的setStatesetState需要传入的就是一个对象

# state 使用时,有以下两种方式

  1. 直接写在类组件里(官方不建议这样用) 可以将state直接写在类组件的Component函数中
// 直接写在类组件里(
export default class App extends Component {
    constructor() {
        super()
    // 这种方式不用constructor构造函数
      }
    // 直接写在类组件里(官方不建议这样写)
    state = {
            name: "上官",
            age: '20'
        };
    // 渲染函数
    render() {
        return (
            <div>
                <h1>
                    开始使用state
                </h1>
                <p>{this.state.name + this.state.age}</p>
            </div>
        )
    }
}
  1. 状态初始在 constructor

这种情况下,构造函数里必须先写 super()class类里的子组件继承了父类后,必须要调用super()超级函数,来初始化一下父类的构造函数,并且得到子类自己的指针.

// react中的state状态案例
import React, { Component } from 'react'
export default class App extends Component {
    // 初始状态
    constructor() {
        super()
        // super()方法必须在构造函数的顶端
        this.state = {
            // 初始化状态
            name: "上官",
            age: '20'
        };
    }
    // 渲染函数
    render() {
        return (
            <div>
                <h1>
                    开始使用state
                </h1>
                <p>{this.state.name + this.state.age}</p>
            </div>
        )
    }
}

# 修改类组件的状态值

  • setState()

语法:this.setState({ name: newText })

  • 实例代码
// 修改状态的案例
import React, { Component } from 'react'
export default class App extends Component {
    // 构造函数
    constructor() {
        //必须这样写
        super()
        //状态的声明
        this.state = {
            count: 0,
            isShow: true
        }
    }
    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.add}>+</button>
                {
                    this.state.isShow && <div style={{ border: "1px solid red" }}>23</div>
                }
                <button onClick={this.show}>显示或隐藏</button>
            </div>
        )
    }
    // 累加的方法
    /*
    add() { }
 常规函数,打印的this时undefined ,有丢失this的现象,所以要用箭头函数, 箭头函数自身没有this,但会在最近的作用域里找this
    */
    add = () => {
        // 修改我们的状态
        this.setState({
        // 在react中state状态只能用setState去修改,不能直接手动修改
            count: this.state.count + 2
        })
    }
    // 控制元素显示隐藏
    show = () => {
        this.setState({
            isShow: !this.state.isShow
        })
        // 等价于
        /* if (this.state.isShow) {
            this.setState({
                isShow: false
            })
        } else {
            this.setState({
                isShow: true
            })
        } */
    }
}

注1:在我们绑定事件函数得时候,this指针丢失得问题,解决方法:声明这个函数得时候用箭头函数

注2:

// 解构赋值的运用
import React, { Component } from 'react'
// 利用es6中数组的解构,对象的解构,来解构Component

注3:凡是直接写在Component {}中的方法,调用的时候都必须加this

注4:修改数据时hooksteState的区别

  • hook :修改状态时新旧值的替换
  • setState :在修改值的时候,实际上是将新旧对象进行合并

# 函数组件

命名规则:

  1. 函数名首字母必须大写:function App(){}
  2. 为什么必须大写?

因为小写的表示原生 html 的标签,但是原生标签里没有这个<app />标签,所以会报错。

  • 官方规定:组件名字首写字母必须大写 英文 _ 456

# 组件的文件命名

  • 给组件起名字的时候,一定不要和原生的标签名一样,不然会报错
  • 如果写的是一个组件,文件的后缀用 .jsx
  • 如果写的是一个 js 文件,文件后缀用 .js

# 函数组件的使用(共三大步骤)

  • App.js文件介绍
// 在组件中,react 核心库是用来解析生成虚拟DOM的,所以必须引入
import React from 'react'
// import 引入组件必须写在文件的最顶端(使用组件第二步共三步)
import Headers from './components/Header-box'
import Main from "./components/Main-box";
import Footer from './components/Footer'
/*
 1. 函数组件的基础
 function App() {
    // 函数里的返回值怎么写---用return
    return <div>你好</div>
}
 2. 基本布局
    <></> 这是一个占位符,它不会再页面上生成任何的标签,只起到一个包裹其他标签的作用
    在写组件的时候,如果有多个同级的标签,必须在同一个根标签里
 */
function App() {
    return (
        <>
            {/* 使用(使用组件第三步共三步) */}
            <Headers />
            <Main />
            <Footer />
        </>
    )
}
// 要用es6的模块
// import 是导入,被导入的组件一定要有对应的导出
export default App
  • Header函数组件本体(另外的两个同下)
//components/Header-box.jsx
// 编写组件内容 (使用组件第一步共三步)
// 1,写组件,第一步 引入react
import React from 'react'
import './Head-box.css' // 引入css文件要写全名 加上.css
// 2. 写函数组件,-- es6 箭头函数
// export default 告诉引入的组件,这个组件里默认导出的就是这个函数
export default () => {
    return (
        <header className="header-box">
            <nav>
                <ul>
                    <li>首页</li>
                    <li>新闻</li>
                    <li>关于</li>
                </ul>
            </nav>
        </header>
    )
}

# 函数组件--属性

  • 属性:props
  • 它是我们组件标签上写的所以键值对的集合是一个{}(Object),
  • 作用是:父组件向子组件传递数据用

# 组合模式 -- 组件组合模式

  1. 高复用模式,说白了,就是一个子组件被多次的调用,传入不同的参数显示不同的内容
  2. 插槽,就是在自定义组件中插入其他的组件

提示

没有特殊情况,推荐使用函数组件,性能好;

在组件⾥⾯我们通过{}JSX⾥⾯渲染变量

最后提交: 7/15/2022, 10:42:12 AM