• 第5章:组件的数据挂载方式


    第5章:组件的数据挂载方式

    状态(state)

    状态就是组件描述某种显示情况的数据, 由组件自己设置和更改, 也就是说由组件自己维护, 使用状态的目的就是为了在不同的状态下使组件的显示不同(自己管理)。

    定义state

    第一种方式

    import React, {Component} from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends Component {
        state = {
            name: 'React',
            isLiked: false
        }
    
        render() {
            return (
                

    欢迎来到{this.state.name}的世界

    ) } } ReactDOM.render(, document.getElementById('root'))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    另一种方式

    import React, {Component} from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends Component {
        constructor() {
            super()
            this.state = {
                name: 'React',
                isLiked: false
            }
        }
    
        render() {
            return (
                

    欢迎来到{this.state.name}的世界

    ) } } ReactDOM.render(, document.getElementById('root'))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    this.state 是纯 js 对象, 在 vue 中, data 属性是利用 Object.defineProperty 处理过的, 更改 data 的数据的时候会触发数据的 gettersetter, 但是 React 中没有做这样的处理, 如果直接更改的话, react 是无法得知的, 所以, 需要使用特殊的更改状态的方法 setState

    setState

    isLiked 存放在实例的 state 对象当中, 组件的 render 函数内, 会根据组件的 state 的中的 isLiked 不同显示“取消”或“收藏”内容。下面给 button 加上了点击的事件监听。

    import React, {Component} from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends Component {
        constructor() {
            super()
            this.state = {
                name: 'React',
                isLiked: false
            }
        }
    
        handleBtnClick = () => {
            this.setState({
                isLiked: !this.state.isLiked
            })
        }
    
        render() {
            return (
                

    欢迎来到{this.state.name}的世界

    ) } } ReactDOM.render(, document.getElementById('root'))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    setState 有两个参数第一个参数可以是对象, 也可以是方法 return 一个对象, 我们把这个参数叫做 updater

    • 参数是对象
    this.setState({
        isLiked: !this.state.isLiked
    })
    
    • 1
    • 2
    • 3
    • 参数是方法
    // 注意的是这个方法接收两个参数,第一个是上一次的state, 第二个是props
    this.setState((prevState, props) => {
        return {
            isLiked: !prevState.isLiked
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    setState 是异步的, 所以想要获取到最新的 state, 没有办法获取, 就有了第二个参数, 这是一个可选的回调函数

    this.setState((prevState, props) => {
        return {
            isLiked: !prevState.isLiked
        }
    }, () => {
        console.log('回调里的', this.state.isLiked)
    })
    console.log('setState外部的', this.state.isLiked)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    属性(props)

    props 是正常是外部传入的, 组件内部也可以通过一些方式来初始化的设置, 属性不能被组件自己更改, 但是你可以通过父组件主动重新渲染的方式来传入新的 props

    属性是描述性质、特点的, 组件自己不能随意更改。

    之前的组件代码里面有 props 的简单使用, 总的来说, 在使用一个组件的时候, 可以把参数放在标签的属性当中, 所有的属性都会作为组件 props 对象的键值。通过箭头函数创建的组件, 需要通过函数的参数来接收 props:

    • 在组件上通过 key=value 写属性,通过 this.props 获取属性, 这样组件的可复用性提高了。
    • 注意在传参数时候, 如果写成 isShow="true" 那么这是一个字符串, 如果写成 isShow={true} 这个是布尔值
    • {...对象} 展开赋值
    • 默认属性值
    *.defaultProps = { }
    static defaultProps = {
        myname: "默认的myname",
        myshow: true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • prop-types 属性验证
    import propTypes from "prop-types";
    *.propTypes = {
        name: propTypes.string,
        age: propTypes.number
    }
    static propTypes = {
        myname: propTypes.string,
        myshow: propTypes.bool
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    属性vs状态

    相似点:

    1. 都是纯 js 对象
    2. 都会触发 render 更新
    3. 都具有确定性(状态/属性相同, 结果相同)

    不同点:

    1. 属性能从父组件获取, 状态不能
    2. 属性可以由父组件修改, 状态不能
    3. 属性能在内部设置默认值, 状态也可以, 设置方式不一样
    4. 属性不在组件内部修改, 状态要在组件内部修改
    5. 属性能设置子组件初始值, 状态不可以
    6. 属性可以修改子组件的值, 状态不可以

    state 的主要作用是用于组件保存、控制、修改自己的可变状态。 state 在组件内部初始化, 可以被组件自身修改, 而外部不能访问也不能修改。你可以认为 state 是一个局部的、只能被组件自身控制的数据源。 state 中状态可以通过 this.setState 方法进行更新, setState 会导致组件的重新渲染。

    props 的主要作用是让使用该组件的父组件可以传入参数来配置该组件。它是外部传进来的配置参数, 组件内部无法控制也无法修改。除非外部组件主动传入新的 props, 否则组件的 props 永远保持不变。

    没有 state 的组件叫无状态组件(stateless component), 设置了 state 的叫做有状态组件(stateful component)。因为状态会带来管理的复杂性, 我们尽量多地写无状态组件, 尽量少地写有状态的组件。这样会降低代码维护的难度, 也会在一定程度上增强组件的可复用性。

    渲染数据

    条件渲染

    {
        condition ? '渲染列表的代码' : '空空如也'
    }
    
    • 1
    • 2
    • 3

    列表渲染

    // 数据
    const people = [{id: 1, name: 'Leo', age: 35}, {
        id: 2, name: 'XiaoMing', age: 16
    }]
    // 渲染列表
    {
        people.map(person => {
            return (
    {person.name}
    age: {person.age}
    ) }) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    React 的高效依赖于所谓的 Virtual-DOM, 尽量不碰 DOM。对于列表元素来说会有一个问题:元素可能会在一个列表中改变位置。要实现这个操作, 只需要交换一下 DOM 位置就行了, 但是 React 并不知道其实我们只是改变了元素的位置, 所以它会重新渲染后面两个元素(再执行 Virtual-DOM), 这样会大大增加 DOM 操作。但如果给每个元素加上唯一的标识, React 就可以知道这两个元素只是交换了位置, 这个标识就是 key, 这个 key 必须是每个元素唯一的标识。

    dangerouslySetInnerHTML

    对于富文本创建的内容, 后台拿到的数据是这样的:

    content = "

    React.js是一个构建UI的库

    "
    • 1

    处于安全的原因, React 当中所有表达式的内容会被转义, 如果直接输入, 标签会被当成文本。这时候
    就需要使用 dangerouslySetHTML 属性, 它允许我们动态设置 innerHTML

    import React, {Component} from 'react'
    import ReactDOM from 'react-dom'
    
    class App extends Component {
        constructor() {
            super()
            this.state = {content: "

    React.js是一个构建UI的库

    "} } render() { return (
    {__html: this.state.content}}/>) } } ReactDOM.render(, document.getElementById('root'))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    un7.30:Linux——如何在docker容器中显示MySQL的中文字符?
    postman教程-13-关联接口调用
    php 日期
    动态规划 拿小球简单版(爱思创)
    【Verilog 教程】7.2 Verilog 文件操作
    1932. 合并多棵二叉搜索树 并查集+DFS
    Ubuntu配置深度学习环境(TensorFlow和PyTorch)
    【Oralce】导出所有表名、表注释、创建时间、最后修改时间、主键
    细说React组件性能优化
    linux tr 删除空行
  • 原文地址:https://blog.csdn.net/m0_51180924/article/details/126378576