React优化性能的hooks,Class类组件,zustand--Redux平替

文章目录

  • useReducer
    • 基础用法
  • useMemo
  • React.memo
    • props的比较机制
  • useCallback
  • React.forwardRef
  • useInperativeHandle
  • Class API
    • 类组件基础结构
    • 类组件的生命周期
    • 类组件的组件通信
  • zustand---Redux平替
    • 使用方法
    • 异步支持
    • 切片模式

useReducer

  • 和useState作用类似,用来管理相对复杂的状态数据

基础用法

  1. 定义一个reducer函数(根据不同的action返回不同的新状态)
  2. 在组件中调用useReducer,并传入reducer函数和状态的初始值
  3. 事件发生时,通过dispatch函数分派一个action对象(通知reducer要返回哪个新状态并渲染UI)
import { useReducer } from "react";

//定义一个reducer函数
const reducer = (state,action)=>{
    switch(action.type){
      case "INC":
        return state + 1;
      case "DEC":
        return state - 1;
      case "SET":
        return action.payload
      default:
        return state
    }
}

function App() {
  //组件中调用useReducer
  const [state,dispatch] = useReducer(reducer,0)
  return (
    <div className="App">
      this is APP
      <button onClick={()=>dispatch({type:"DEC"})}>-</button>
      {state}
      <button onClick={()=>dispatch({type:"INC"})}>+</button>
      <button onClick={()=>dispatch({type:"SET",payload:100})}>update</button>

    </div>
  );
}

export default App;

useMemo

  • 作用:在组件每次重新渲染的时候缓存计算的结果,避免了性能浪费
    说明:使用useMemo做缓存之后可以保证只有依赖项发生变化时才会重新计算
useMemo(()=>{
    
},[count])
//count为依赖项

React.memo

  • 作用:允许组件在Props没有改变的情况下跳过渲染
    React组件默认的渲染机制:只要父组件重新渲染子组件就会重新渲染
const MemoComponent = memo(function SomeComponent(props){
    // ...
})
  • 经过memo函数包裹生成的缓存组件只有在props发生变化的时候才会重新渲染

props的比较机制

  • 机制:在使用memo缓存组件之后,React会对每一个prop使用Object.is比较新值和老值,返回true则表示没有变化
  • 传递一个普通类型的prop:prop变化时组件重新渲染
  • 传递一个引用类型的prop:比较的是新值和旧值的引用是否相等,当父组件的函数重新执行时,实际上形成的是新的数组引用

useCallback

  • 作用:在组件多次重新渲染的时候缓存函数
  • 说明:使用useCallback包裹函数之后,函数可以保证在APP重新渲染时保持引用稳定
import { memo, useCallback, useReducer, useState } from "react";

const Input = memo(function Input({onChange}){
  console.log("子组件重新渲染了");
  return <input type="text" onChange={(e)=>{onChange(e.target.value)}}></input>
  
})

function App() {
  const [count,setCount] = useState(0)
  const changeHandler = useCallback((value)=>console.log(value),[])
  return (
    <div className="App">
      <Input onChange={changeHandler} />
      <button onClick={()=>{setCount(count+1)}}>{count}</button>
    </div>
  );
}

export default App;

React.forwardRef

  • 父组件拿到子组件的DOM元素
import { forwardRef, memo, useCallback, useReducer, useRef, useState } from "react";

const Input = forwardRef((props,ref)=>{
  return <input ref={ref} type="text"></input>
})

function App() {
  const inputref = useRef(null)
  const showRef = ()=>{
    console.log(inputref);
    inputref.current.focus()
  }
  return (
    <div className="App">
        <Input ref={inputref} />
        <button onClick={showRef}>ref</button>
    </div>
  );
}

export default App;

useInperativeHandle

  • 通过ref暴露子组件中的方法
  • 步骤:
    • 在子组件中编写方法
    • 通过useInperativeHandle暴露出来
    • 父组件通过绑定到子组件上的ref来使用子组件中的方法
import { forwardRef, memo, useCallback, useImperativeHandle, useReducer, useRef, useState } from "react";

const Input = forwardRef((props,ref)=>{
  const inputRef = useRef(null)
  //编写聚焦逻辑
  const focusHandler = ()=>{
    inputRef.current.focus()
  }
  //向外层暴露方法
  useImperativeHandle(ref,()=>{
    return {
      focusHandler
    }
  })
  return <input ref={inputRef} type="text"></input>
})

function App() {
  const inputref = useRef(null)
  const showRef = ()=>{
    console.log(inputref);
    inputref.current.focusHandler()
  }
  return (
    <div className="App">
        <Input ref={inputref} />
        <button onClick={showRef}>ref</button>
    </div>
  );
}

export default App;

Class API

类组件基础结构

  • 类组件就是通过JS中的类来组织组件的代码
  1. 通过类属性state定义状态数据
  2. 通过setState方法来修改状态数据
  3. 通过render来写UI模版(JSX语法一致)
import { Component, forwardRef, memo, useCallback, useImperativeHandle, useReducer, useRef, useState } from "react";

//ClassAPI
class Counter extends Component{
  //定义状态变量
  state = {
    count:0
  }
  //定义事件回调修改状态变量
  setCount = ()=>{
    this.setState({
      count: this.state.count + 1
    })
  }

  //通过render函数返回UI模版
  render(){
    return <button onClick={this.setCount}>{this.state.count}</button>
  }
}

function App() {

  return (
    <div className="App">
        <Counter />
    </div>
  );
}

export default App;

类组件的生命周期

  • 组件从创建到销毁的各个阶段自动执行的函数就是生命周期函数
    React优化性能的hooks,Class类组件,zustand--Redux平替_第1张图片

类组件的组件通信

  • 类组件和Hooks编写的组件在组件通信上的思路是一致的
  1. 父传子:通过prop绑定数据
  2. 字传父:通过prop绑定父组件中的函数,子组件调用
  3. 兄弟通信:状态提升,通过父组件做桥接

zustand—Redux平替

使用方法

  1. 使用create函数创建一个状态管理的存储store
  2. 在store中定义状态数据和修改状态数据的方法
  3. 在组件中使用store,将store中的状态变量和方法结构出来进行使用即可
import { create } from "zustand";

//创建store
const useStore = create((set)=>{
  return {
    //状态数据
    count:0,
    //修改状态数据
    inc:()=>{
      set((state)=>{return {count:state.count + 1}})
    }
  }
})

function App() {
  //实例store并结构数据
  const {count,inc} = useStore()
  return (
    <div className="App">
        <button onClick={inc}>{count}</button>
    </div>
  );
}

export default App;

注意:

  1. 函数参数必须返回一个对象,对象内部编写状态数据和方法
  2. set是用来修改数据的专门方法必须调用它来修改数据

异步支持

  • 直接在函数中编写异步逻辑,最后只需要调用set方法传入新状态即可

React优化性能的hooks,Class类组件,zustand--Redux平替_第2张图片

切片模式

  • 当单个store比较大时,可以采用切片模式进行模块的拆分组合,类似于模块化
    React优化性能的hooks,Class类组件,zustand--Redux平替_第3张图片

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