• 【React扩展】1、setState的两种写法、lazyLoad懒加载、Fragment标签和createContext()


    在这里插入图片描述

    欢迎来到我的博客
    📔博主是一名大学在读本科生,主要学习方向是前端。
    🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
    🛠目前正在学习的是🔥 R e a c t 框架 React框架 React框架🔥,中间穿插了一些基础知识的回顾
    🌈博客主页👉codeMak1r.小新的博客

    本文被专栏【React–从基础到实战】收录

    🕹坚持创作✏️,一起学习📖,码出未来👨🏻‍💻!
    在这里插入图片描述

    1. setState

    setState更新状态的2种写法

    (1). setState(stateChange, [callback]) -----对象式的setState

    this.setState({ count: count + 1 }, () => {
      // render调用后
      console.log(this.state.count)
    });
    
    • 1
    • 2
    • 3
    • 4
    1. stateChange为状态改变对象,该对象可以体现出状态的更改;
    2. callback是可选的回调函数,它在状态更新完毕,页面也更新后(render调用后)才被调用

    (2). setState(updater, [callback]) ----- 函数式的setState

    this.setState((state, props) => {
      console.log(state, props)
      return { count: state.count + 1 }
    });
    
    • 1
    • 2
    • 3
    • 4
    1. updater为返回stateChange对象的函数;
    2. updater可以接收到state和props;
    3. callback是可选的回调函数,它在状态更新、页面也更新后(render调用后)才被调用

    总结:

    1. 对象式的setState是函数式的setState的简写方式(语法糖)

    2. 使用原则:

      (1)如果新状态不依赖于原状态 ==== 使用对象方式

      (2)如果新状态依赖于原状态 ==== 使用函数方式

      (3)如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取

    3. React状态的更新是异步的!!

    2.lazyLoad

    路由组件的lazyLoad

    引入lazy函数和Suspense组件

    import React, { Component, lazy, Suspense } from 'react'
    
    • 1

    实现路由懒加载

    // 1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
    const Login = lazy(() => import('@/pages/Login'))
    
    // 2. 通过指定在加载得到路由打包文件前显示一个自定义loading界面
    <Suspense fallback={<h1>loading</h1>}>
      <Switch>
        <Route path="/xxx" component={xxx}/>
      	<Redirect to="/login"/>
      </Switch>
    </Suspense>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3. Fragment

    使用

    // Componment
    import React, { Component, Fragment } from 'react'
    import Demo from './components/4_fragment'
    
    export default class App extends Component {
      render() {
        return (
          <Fragment>
            <Demo />
          </Fragment>
        )
      }
    }
    
    // FC
    import React, { Fragment } from 'react'
    
    export default function Demo() {
      return (
        <Fragment>
          <input type="text" />
          <input type="text" />
        </Fragment>
      )
    }
    其实还可以...
    import React from 'react'
    
    export default function Demo() {
      return (
        <>
          <input type="text" />
          <input type="text" />
        </>
      )
    }
    
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    作用

    可以不用必须有一个真实的DOM根标签了

    4.createContext()

    理解

    一种组件间通信方式,常用于【祖组件】与【后代组件】间通信

    在这里插入图片描述

    使用

    1. 创建Context容器对象:

      const Xxxcontext = React.createContext()
      
      • 1
    2. 渲染子组件时,外面包裹xxxContext.Provider,通过value属性给后代组件传递数据:

      <XxxContext.Provider value={数据}>
      	子组件
      </XxxContext.Provider>
      
      • 1
      • 2
      • 3
    3. 后代组件读取数据:

      // 第一种方式:仅适用于类组件
      static contextType = xxxContext // 声明接收context
      this.context // 读取context中的value数据
      
      // 第二种方式:函数组件与类组件都可以
      <xxxContext.Consumer>
      	{
      		value => ( //value就是context中的value数据
      			要显示内容
      		)
      	}
      </xxxContext.Consumer>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

    示例

    A组件是父组件;B组件是子组件;C组件是孙组件

    A组件中初始化了state,里面有一个username属性值为tom;

    孙组件C要使用A组件传递过来的username属性。

    在这里插入图片描述

    import React, { Component } from 'react'
    import './index.css'
    
    // 创建一个用于保存数据的上下文
    const MyContext = React.createContext()
    export default class A extends Component {
    
      state = { username: 'tom' }
    
      render() {
        return (
          <div className='parent'>
            <h3>我是A组件</h3>
            <h4>我的用户名是:{this.state.username}</h4>
            <MyContext.Provider value={this.state.username}>
              <B />
            </MyContext.Provider>
          </div>
        )
      }
    }
    
    class B extends Component {
      render() {
        return (
          <div className='child'>
            <h3>我是B组件</h3>
            <C />
          </div>
        )
      }
    }
    
    class C extends Component {
      // 声明接收context
      static contextType = MyContext
      render() {
        console.log(this)
        return (
          <div className='grand'>
            <h3>我是C组件</h3>
            <h4>我从A组件接收到的用户名:{this.context}</h4>
          </div>
        )
      }
    }
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    若孙组件C为函数式组件FC:

    function C() {
      return (
        <div className='grand'>
          <h3>我是C组件</h3>
          <h4>我从A组件接收到的用户名:
            <MyContext.Consumer>
              {
                value => {
                  return value
                }
              }
            </MyContext.Consumer>
          </h4>
        </div>
      )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意

    在应用开发中一般不用context,一般都用它来封装react插件;

    比如:react-redux库底层就使用到了context…

  • 相关阅读:
    重学前端——npm yarn pnpm
    HIve项目中常见错误,及修改办法
    模拟shell小程序
    2、xss-labs之level2
    LeetCode每日一题(1599. Maximum Profit of Operating a Centennial Wheel)
    一名GISer的本科生涯--写于2018年
    zabbix告警 邮件告警 钉钉告警
    8080并行接口
    win10安全中心打开是空白的怎么解决
    pandas 筛选数据的 8 个骚操作
  • 原文地址:https://blog.csdn.net/Svik_zy/article/details/126079130