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应用程序。在使用钩子时,选择适当的钩子来解决您的问题,并根据需要组合使用它们,以获得最佳性能和可维护性。

相关推荐
也无晴也无风雨36 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤5 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui