【React 框架】setState / Lazy loading / Hooks / Fragments / Context / PureComponent / render props / ...

一、setState

        官方文档:React.Component – React

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

        (1)stateChange 为状态改变对象 ( 该对象可以体现出状态的更改 )。

        (2)callback 是可选的回调函数,它在状态更新完毕、界面也更新后 ( render 调用后 ) 才被调用。

        // 1. 对象式写法
        const { count } = this.state
        this.setState({ count: count + 1 }, () => {
            console.log('对象式写法:', this.state.count);
        })

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

        (1)updater 为返回 stateChange 对象的函数。

        (2)updater 可以接收到 state 和 props。

        (3)callback 是可选的回调函数,它在状态更新、界面也更新后 ( render调用后 ) 才被调用。

        // 2. 函数式写法
        this.setState(
            (state, props) => {
                return { count: state.count + 1 }
            },
            () => { console.log('函数式写法:', this.state.count); })

总结:

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

(2)使用原则:(也不一定按照这个,看自己方便选叭)

         ① 如果新状态不依赖于原状态 ===> 使用对象方式

         ② 如果新状态依赖于原状态 ===> 使用函数方式

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

二、Lazy loading

        说明:React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件)。

        (就是比如有100个组件,你只打开了3个,默认情况下是页面直接加载了100个组件,加了 lazy 函数之后只加载用到的组件)

        官方文档:代码分割 – React

// 导入模块
import React, { Component, lazy, Suspense} from 'react'

// loading 为兜底的模块,假设网速比较慢,组件还未出来时加载 loading 组件
import Loading from './Loading'

//通过 React 的 lazy 函数配合 import() 函数动态加载路由组件 ===> 路由组件代码会被分开打包
const Home = lazy(()=> import('./Home') )
const About = lazy(()=> import('./About'))
// 通过  指定在加载得到路由打包文件前显示一个自定义 loading 界面
}>
    {/* 注册路由 */}
    
    

三、Hooks

1、概述

        官方文档:Hook 概览 – React

        Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

React Hook / Hooks 是什么?

        (1)Hook是React 16.8.0版本增加的新特性 / 新语法。

        (2)可以让你在函数组件中使用 state 以及其他的 React 特性。

三个常用的 Hook:

        (1)State Hook:React.useState()。

        (2)Effect Hook:React.useEffect()。

        (3)Ref Hook:React.useRef()。

2、State Hook

(1)State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作。

(2)语法:const [xxx, setXxx] = React.useState(initValue)  。

(3)useState() 说明:

         参数:第一次初始化指定的值在内部作缓存。

         返回值:包含2个元素的数组,第1个为内部当前状态值,第2个为更新状态值的函数。

(4)setXxx() 2种写法:

         setXxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值。

         setXxx(value => newValue):参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值。

import React from 'react'

export default function App() {

    // const [状态, 更新状态的方法] = React.useState(initValue) 
    const [count, setCount] = React.useState(0);

    function add() {
        setCount(count + 1);
    }

    return (
        

此组件的和为:{count}

) }

3、Effect Hook

(1)Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)。

(2)React中的副作用操作:

         ① 发ajax请求数据获取。

         ② 设置订阅 / 启动定时器。

         ③ 手动更改真实DOM。

(3)语法和说明:

        useEffect(() => {
          // 在此可以执行任何带副作用操作
          return () => { // 在组件卸载前执行
            // 在此做一些收尾工作, 比如清除定时器/取消订阅等
          }
        }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行

(4)可以把 useEffect Hook 看做如下三个函数的组合:

         componentDidMount()

         componentDidUpdate()

         componentWillUnmount()

import React from 'react'
import { root } from '.';

export default function App() {

    // const [状态, 更新状态的方法] = React.useState(initValue) 
    const [count, setCount] = React.useState(0);

    function add() {
        setCount(count + 1);
    }

    function unmountNode() {
        root.unmount()
    }

    React.useEffect(() => {
        const timer = setInterval(() => {
            // 这里设置的是刷新页面后 count 定时自增 1 
            setCount(count => count + 1);
        }, 500);
        return () => {
            // 相当于 componentWillUnmount()
            // 清除定时器
            clearInterval(timer);
        }
    }, []); 
    // 如果第二个参数为 [], 则相当于 componentDidMount()
    // 如果第二个参数有具体的值 [count], 则相当于 componentDidUpdate(), 会监测数据的更新

    return (
        

此组件的和为:{count}

) }

4、Ref Hook

(1)Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据。

(2)语法:const refContainer = useRef()。

(3)作用:保存标签对象,功能与React.createRef()一样。

import React from 'react'

export default function App() {
    const ref = React.useRef();

    function show() {
        console.log(ref.current.value);
    }

    return (
        
) }

四、Fragments

        官方文档:Fragments – React

        React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。

    render() {
      return (
        
          
          
          
        
      );
    }

五、Context

1、概述

        官方文档:Context – React

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

2、使用

(1) 创建 Context 容器对象。

const XxxContext = React.createContext() 

(2)渲染子组时,外面包裹 xxxContext.Provider,通过value属性给后代组件传递数据。

	
		子组件
    

(3)后代组件读取数据。

    //第一种方式:仅适用于类组件 
	  static contextType = xxxContext  // 声明接收context
	  this.context // 读取context中的value数据
	  
	//第二种方式: 函数组件与类组件都可以
	  
	    {
	      value => ( // value就是context中的value数据
	        要显示的内容
	      )
	    }
	  

六、PureComponent

1、Component 的 2 个问题

        (1)只要执行 setState(),即使不改变状态数据,组件也会重新render()。

        (2)只当前组件重新 render(),就会自动重新 render 子组件 ==> 效率低。

        (3)原因:Component 中的 shouldComponentUpdate() 总是返回 true。

        (4)效率高的做法:只有当组件的 state 或 props 数据发生改变时才重新 render()。

2、解决方法:

2.1 重写 shouldComponentUpdate() 方法

        比较新旧 state 或 props 数据,如果有变化才返回 true,如果没有返回 false。

    shouldComponentUpdate(nextProps,nextState){
		console.log(this.props,this.state); // 目前的props和state
		console.log(nextProps,nextState); // 接下要变化的目标props,目标state
		return !this.state.carName === nextState.carName
	}

2.2 使用 PureComponent

        官方文档:React 顶层 API – React

        PureComponent 重写了 shouldComponentUpdate(),只有 state 或 props 数据有变化才返回 true。

// 导入 PureComponent 就行
import React, { PureComponent } from 'react'

【React 框架】setState / Lazy loading / Hooks / Fragments / Context / PureComponent / render props / ..._第1张图片

七、render props 

        官方文档:Render Props – React

如何向组件内部动态传入带内容的结构(标签)?   

        (1)使用 children props:通过组件标签体传入结构。

        (2)使用render props:通过组件标签属性传入结构,一般用 render 函数属性。

children props:

    
      xxxx
    
    {this.props.children}

  问题:如果 B 组件需要 A 组件内的数据  ==> 做不到

render props:

         }>

        A组件:{this.props.render(内部state数据)}

        C组件:读取A组件传入的数据显示 {this.props.data}

八、错误边界 ErrorBoundary

        官方文档:错误边界 – React

        理解:用来捕获后代组件错误,渲染出备用页面。

        特点:只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误。

使用方式:getDerivedStateFromError 配合 componentDidCatch

// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前触发
    // 返回新的state
    return {
        hasError: true,
    };
}

componentDidCatch(error, info) {
    // 统计页面的错误。发送请求发送到后台去
    console.log(error, info);
}

九、组件通信方式总结

1、几种通信方式

        (1)props:① children props。② render props。

        (2)消息订阅-发布:pubs-sub、event 等等。

        (3)集中式管理:redux、dva 等等。

        (4)conText:生产者-消费者模式。

2、组件间的关系 + 搭配

        (1)父子组件:props。

        (2)兄弟组件(非嵌套组件):消息订阅-发布、集中式管理。

        (3)祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(用的少)。

你可能感兴趣的:(前端,react.js,java,前端,javascript,react)