0901扩展-react

文章目录

    • 1. setState
    • 2. lazyLoad
    • 3. Hooks
      • 3.1 React Hook/Hooks是什么?
      • 3.2 State Hook
      • 3.4 Effect Hook
      • 3.5 Ref Hook
    • 4. Fragment
    • 5. Context
    • 6. 组件优化
    • 7. render props
    • 8. 错误边界
    • 9. 组件通信方式总结
    • 结语

1. setState

  • setState更新状态的2种写法
	(1). setState(stateChange, [callback])------对象式的setState
            1.stateChange为状态改变对象(该对象可以体现出状态的更改)
            2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
					
	(2). setState(updater, [callback])------函数式的setState
            1.updater为返回stateChange对象的函数。
            2.updater可以接收到state和props。
            4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
总结:
		1.对象式的setState是函数式的setState的简写方式(语法糖)
		2.使用原则:
				(1).如果新状态不依赖于原状态 ===> 使用对象方式
				(2).如果新状态依赖于原状态 ===> 使用函数方式
				(3).如果需要在setState()执行后获取最新的状态数据, 
					要在第二个callback函数中读取

1_setState/index.jsx源代码1-1如下所示:

import React, { Component } from 'react'

export default class Demo extends Component {

  state = { count: 0 }

  /**
   * 自增
   */
  add = () => {
    // 对象式setState
    // // 1 获取原值
    // const {count } = this.state
    // // 2 更新状态
    // this.setState({count: count + 1})

    // 函数式setState
    this.setState(state => ({count : state.count + 1}))
  }

  render() {
    return (
      

当前求和为: {this.state.count}

) } }

2. lazyLoad

  • 路由组件的lazyLoad
	//1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
	const Login = lazy(()=>import('@/pages/Login'))
	
	//2.通过指定在加载得到路由打包文件前显示一个自定义loading界面
	loading.....}>
        
            
            
        
    

示例2_lazyLoad/index.jsx如下所示:

import React, { Component, lazy, Suspense } from 'react'
import { Route, NavLink } from "react-router-dom";
// import About from './About'
// import Home from './Home'
import Loading from './Loading';
// 路由组件懒加载
const Home = lazy(() => import('./Home'))
const About = lazy(() => import('./About'))

export default class Demo extends Component {
  render() {
    return (
      

React Router demo

{/* react中靠路由链接实现组件切换--编写路由链接 */} About Home
}> {/* 注册路由 */}
) } }

3. Hooks

3.1 React Hook/Hooks是什么?

(1). Hook是React 16.8.0版本增加的新特性/新语法
(2). 可以让你在函数组件中使用 state 以及其他的 React 特性
    1. 三个常用的Hook
(1). State Hook: React.useState()
(2). Effect Hook: React.useEffect()
(3). Ref Hook: React.useRef()

3.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): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

示例代码3_stateHooks/jsx代码如下所示:

import React, { Component } from 'react'

// 类式组件
// class Demo extends Component {

//   state = { count: 0 }


//   /**
//    * 自增
//    */
//   add = () => {
//     this.setState(state => ({count : state.count + 1}))
//   }

//   render() {
//     return (
//       
//

当前求和为: {this.state.count}

// //
// ) // } // } // 函数式组件 function Demo() { const [count, setCount] = React.useState(0) const [name, setName] = React.useState('tom') function add() { // console.log('-----'); // setCount(count + 1) setCount(count => count + 1) } function changeName() { setName('jimi') } return (

当前求和为: {count}

我的名字: {name}

) } export default Demo

3.4 Effect Hook

(1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
(2). React中的副作用操作:
        发ajax请求数据获取
        设置订阅 / 启动定时器
        手动更改真实DOM
(3). 语法和说明: 
        useEffect(() => { 
          // 在此可以执行任何带副作用操作
          return () => { // 在组件卸载前执行
            // 在此做一些收尾工作, 比如清除定时器/取消订阅等
          }
        }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
    
(4). 可以把 useEffect Hook 看做如下三个函数的组合
        componentDidMount()
        componentDidUpdate()
    	componentWillUnmount() 

示例3_hooks/index.jsx代码如下:

import React, { Component } from 'react'
import ReactDOM from 'react-dom';
import { root } from "../../index";

// 类式组件
// class Demo extends Component {

//   state = { count: 0 }


//   /**
//    * 自增
//    */
//   add = () => {
//     this.setState(state => ({count : state.count + 1}))
//   }

//   /**
//    * 设置定时器
//    */
//   componentDidMount() {
//     this.timer = setInterval(() => {
//       // 自增1
//       this.add()
//     }, 500);
//   }

//   componentWillUnmount() {
//     clearInterval(this.timer)
//   }

//   render() {
//     return (
//       
//

当前求和为: {this.state.count}

// //
// ) // } // } // 函数式组件 function Demo() { const [count, setCount] = React.useState(0) React.useEffect(() => { const timer = setInterval(() => { add() }, 500); return () => { // 组件卸载之前执行 类似于类组件的钩子函数componentWillUnmount() clearInterval(timer) } }, []) /** * count + 1 */ function add() { setCount(count => count + 1) } /** * 卸载组件 */ function unmount() { // ReactDOM.unmountComponentAtNode(document.getElementById('root')) root.unmount() } return (

当前求和为: {count}

) } export default Demo

3.5 Ref Hook

(1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
(2). 语法: const refContainer = useRef()
(3). 作用:保存标签对象,功能与React.createRef()一样

示例3_hooks/index.jsx代码如下所示:

import React, { Component } from 'react'
import ReactDOM from 'react-dom';
import { root } from "../../index";

// 类式组件
// class Demo extends Component {

//   state = { count: 0 }

//   myRef = React.createRef()

//   /**
//    * 自增
//    */
//   add = () => {
//     this.setState(state => ({count : state.count + 1}))
//   }

//   show = () => {
//     alert(this.myRef.current.value)
//   }

//   /**
//    * 设置定时器
//    */
//   componentDidMount() {
//     this.timer = setInterval(() => {
//       // 自增1
//       this.add()
//     }, 500);
//   }

//   componentWillUnmount() {
//     clearInterval(this.timer)
//   }

//   render() {
//     return (
//       
// //

当前求和为: {this.state.count}

// // //
// ) // } // } // 函数式组件 function Demo() { const [count, setCount] = React.useState(0) const myRef = React.useRef() // React.useEffect(() => { // const timer = setInterval(() => { // add() // }, 500); // return () => { // // 组件卸载之前执行 类似于类组件的钩子函数componentWillUnmount() // clearInterval(timer) // } // }, []) /** * count + 1 */ function add() { setCount(count => count + 1) } /** * 展示输入信息 */ function show() { alert(myRef.current.value) } /** * 卸载组件 */ function unmount() { // ReactDOM.unmountComponentAtNode(document.getElementById('root')) root.unmount() } return (

当前求和为: {count}

) } export default Demo

4. Fragment

  • 使用


    <>

  • 作用

可以不用必须有一个真实的DOM根标签了,效果同vue中插槽