React中的Hooks

本文作者系360奇舞团前端开发工程师

Hooks的作用

Hooks是 React 16.8 版本引入的一项特性,它允许在函数式组件中使用状态和其他 React 特性,而不需要使用类组件。Hooks就是钩子,作用是把某个目标结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果。

常用的钩子

useState

  1. useState(initialState)有一个初始化值作为参数,initialState可以是任意值
  2. 返回包含两个值数组,第一个是值,第二个是set方法

需要注意的一点,setCount后,直接获取count,count的值是不变的,这是因为useState 是一个异步操作,它并不会立即更新状态。当你在函数组件中调用 useState 更新状态时,React 会将新的状态安排进下一次渲染,并在之后的某个时候才会执行更新,这导致在更新状态后立即访问该状态可能会得到之前的值,而不是最新的值。

javascript 复制代码
这是一个useState简单使用实例
function Plus() {
  const [count, setCount] = useState(1);
  function counter(){
     setCount(count+1)
  }
  return (
    <div className='plus'>
        <div>{count}</div>
     <div className='plus-click' onClick={counter}>+</div>
          
    </div>
  );
}

useEffect(执行副作用)

副作用是指一段和当前执行结果无关的代码,比如说要修改函数外部的某个变量,要发起一个请求有两个参数。useEffect有两个参数第一个参数是callback,第二个是个依赖数组,这个数组可以为空

javascript 复制代码
在这里count的值发生变化时,clikValue的值及跟着变化,在这个callback里也可以发起网络请求
function CountPlus() {
  const [count, setCount] = useState(0);
  const [clikValue, setClickValue] = useState("");

  useEffect(() =>{
    setClickValue("我点击了"+count+"次")

  },[count])
  function counter(){
     setCount(count+1)
  }
  return (
    <div className='plus'>
        <div>{count}</div>
      <div className='plus-click' onClick={counter}>+</div>
      <div>{clikValue}</div>
          
    </div>
  );
}
export default CountPlus;

useContext

可以用来在组件树中传递数据

javascript 复制代码
User:是消费提供的值的地方
import React, { useContext  } from 'react';
import UserContext from './UserContext';
import '.././index.css';

function User() {
  const user = useContext(UserContext)

  return (
    <div className='plus'>
      <p>{user.name}</p>
      <p>{user.sex}</p>
    </div>
  );
}
export default User;
javascript 复制代码
UserContext:创建上下文

import { createContext } from 'react';

const UserContext = createContext();

export default UserContext;
javascript 复制代码
App:是提供上下文值的地方
import User from "./componts/User";
import UserContext from "./componts/UserContext";
import './App.css';
function App() {
  return (
    <div className="App">
      <UserContext.Provider value={{ name: '张三', sex: '男' }}>
         <User></User>
      </UserContext.Provider>
    </div>
  );
}

export default App;

useReducer

用于在函数组件中处理复杂的状态逻辑。它通常用于管理具有复杂状态和行为的组件,尤其是涉及到多个状态转换的情况。useReducer 接受两个参数:一个是包含状态转换逻辑的函数(reducer),另一个是初始状态。它返回一个包含当前状态和 dispatch 函数的数组。

javascript 复制代码
import CountDis from "./componts/CountDis";
import './App.css';
import React, { useReducer } from 'react'
const reducer = (state, action) => {
  switch (action.type) {
    case 'count':
      return { ...state, count: state.count + 1 }
    default:
      return state
  }
}
function App() {
  const [useState, dispatch] = useReducer(reducer, { count: 0 })
  return (
    <div className="App">
      <p>点击了 {useState.count}次</p>
      <CountDis dispatch={dispatch}></CountDis>
    </div>
  );
}

export default App;
javascript 复制代码
import React from 'react';
import '.././index.css';

function CountDis({dispatch}) {

  function counter(){
    dispatch({ type: 'count' })
  }
  return (
    <div className='plus'>
     <div className='plus-click' onClick={counter}>+</div>     
    </div>
  );
}
export default CountDis;

useRef

useRef主要用于在函数组件中保存和访问可变的 ref 对象。useRef 返回一个包含 current 属性的对象,该属性被初始化为传入的参数(任意数据类型) 主要作用

  • 访问Dom元素
  • 保存变量、
javascript 复制代码
function CountRef() {
  const inputRef = useRef(null);
  // 使用 ref 访问 DOM 元素
  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }, []);
  function counter() {
   alert(inputRef.current.value)
  }
  return (
    <div className='plus'>
      <p>{inputRef.current}</p>
      <input ref={inputRef}></input>
      <div className='plus-click' onClick={counter}>+</div> 
    </div>
  );
}
export default CountRef;

useCallback

useCallback 的主要目的是性能优化 用于缓存回调函数,以便在依赖项变化时避免不必要的函数重新创建。在 React 中,每当函数组件重新渲染时,函数组件的所有局部变量都会重新初始化。如果将一个新的函数作为 prop 传递给子组件,即使这个函数具有相同的逻辑,由于它是一个新的引用,子组件可能会被重新渲染,从而可能引起性能问题。

javascript 复制代码
function CountUseCallback() {
  const [count, setCount] = useState(1);
  const handleClick = useCallback(() => {
    // 处理点击事件逻辑
          setCount(count+1)
  }, []); 
  return (
    <div className='plus'>
        <div>{count}</div>
      <div className='plus-click' onClick={handleClick}>+</div>
          
    </div>
  );
}
export default CountUseCallback;

useMemo

用于在渲染过程中缓存和重用计算昂贵的值。它类似于 useCallback,但是主要用于缓存计算结果,而不是缓存回调函数。

javascript 复制代码
function CountMemo({size}) {
  let result = useMemo(() => {
    return comuteData()
  }, [size])

   function comuteData(){
    if(size<0){
      return 0
    }
    let sum = 0
    for(let i =1;i<=size;i++){
      sum+=i
    }
    return sum
  }
  
  return (
    <div className='plus'>
      <p>{result}</p>
     
          
    </div>
  );
}
export default CountMemo;

总结

上述的钩子里useState,useEffect,useReducer,useRef本人用的较为多些,useContext ,useMemo和useCallback用的少些。除了上述钩子之外,还有useImperativeHandle、useLayoutEffect、自定义钩子等其他用途的钩子。通过深入了解和熟练使用这些钩子,我们可以更有效地构建强大而灵活的React应用程序。在使用钩子时,选择适当的钩子来解决您的问题,并根据需要组合使用它们,以获得最佳性能和可维护性。

相关推荐
To_OC4 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic4 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy4 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志5 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble6 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯7 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜7 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司8 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
kaiking_g8 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js
江华森8 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http