react-常用hooks的基本使用demo记录

常用hooks

1. useState

state发生变化会引起组件的重新render

复制import { useState } from 'react'
export default function Test() {
    const [num, setNum] = useState(0);
    return <div onClick={() => {
        setNum(v => v + 1);
        // setNum(num + 1);
    }}>
    This is a test demo.<br/>
    The current num is ${num}
    </div>
}

setNum(v => v + 1)与setNum(num + 1)效果一样

2. useEffect

  • 依赖不同有不同的影响
    • 没有依赖
      • 每次render执行后都会执行
    • 依赖是一个空数组
      • 第一次render执行后执行
    • 依赖中有内容
      • 第一次render执行/依赖的内容发生变化后执行
  • 是否有返回值的影响
    • 有返回值
      • 该useEffect(不影响其他useEffect)在下次被执行前/组件卸载时会执行它的返回值。可以用来处理事件的解绑
    • 无返回值
      • 无影响
import { useState, useEffect, useRef } from 'react'
export default function Test() {
    const [num, setNum] = useState(0);
    const ref = useRef(null);
    useEffect(() => {
        console.log('函数每次render我都会执行')
    });
    
    useEffect(() => {
        console.log('我仅在函数第一次render后和num发生变化后执行')
    }, [num]);

    useEffect(() => {
        console.log('我仅在函数第一次render后执行')
        const mouseEnterFunc = () => {
            console.log('触发了mouseenter函数')
        }
        ref.current.addEventListener('mouseenter', mouseEnterFunc);
        return () => {
            ref.current.removeEventListener('mouseenter', mouseEnterFunc);
        }
    }, []);    
    return <div ref={ref} onClick={() => {
        setNum(v => v + 1);
        // setNum(num + 1);
    }}>
    This is a test demo.<br/>
    The current num is ${num}
    </div>
}

3. useCallback

返回传入的函数,依赖影响同useEffect
用来保证在依赖变化的时候,可以一直拿到相同引用的函数。可以做组件对函数存在依赖的情况下的优化,减少渲染次数

import { useState, useCallback } from 'react'
function Test() {
    const [num, setNum] = useState(0);
    const clickFunc = useCallback(() => {
        setNum(v => v + 1);
        console.log('当前的num值为:', num)
    }, [num]);
    return <div onClick={clickFunc}>
    This is a test demo.<br/>
    The current num is ${num}
    </div>
}

4. useMemo

执行传入的函数,返回函数的返回值。依赖影响同useEffect
可以缓存组件,减少父组件重新渲染造成的子组件不必要的渲染

import { useState, useCallback, useMemo } from "react";
function Test() {
  const [num, setNum] = useState(0);
  const clickFunc = useCallback(() => {
    setNum((v) => v + 1);
    console.log("当前的num值为:", num);
  }, [num]);
  console.log("test component is rending.");
  return (
    <div onClick={clickFunc}>
      This is a test demo.
      <br />
      The current num is ${num}
    </div>
  );
}

export default function App() {
  const [name, setName] = useState("xxx");
  const testMemo = useMemo(() => <Test />, []);
  return (
    <div>
      My name is ${name}
      <button
        onClick={() => {
          setName(`xxx-${Math.random()}`);
        }}
      >
        update name
      </button>
      <br />
      I'm app component and that is test component below.
      {testMemo}
    </div>
  );
}

上面例子中,App组件中的state变化时不会造成Test组件的重新渲染

5. useRef

返回的值,在整个生命周期内都存在。可以用来保存一些跨生命周期的值/原始dom节点。
xxx.current的值发生变化不会造成组件的重新渲染。

import { useState, useRef } from 'react'
export default function Test() {
    const [num, setNum] = useState(0);
    const ref = useRef('随便写,不重复就行');
    const countRef = useRef(num);
    return <div ref={ref} onClick={() => {
        setNum(v => v + 1);
        console.log('ref是什么?', ref, ref.current, countRef.current)
        countRef.current = num;
    }}>
    This is a test demo.<br/>
    The current num is ${num}
    </div>
}

6. useContext

搭配createContext使用。用来共享值给多个子组件

import { useContext, createContext } from "react";
const MyContext = createContext({});
function Test() {
  const { test } = useContext(MyContext);
  return <span>{test}</span>;
}
function Test2() {
  const { test2 } = useContext(MyContext);
  return <span>{test2}</span>;
}

export default function App() {
  return (
    <MyContext.Provider
      value={{
        test: "I'm test.",
        test2: "I'm test two."
      }}
    >
      <Test />
      <br />
      <Test2 />
    </MyContext.Provider>
  );
}

7. useReducer

用来集中管理组件中的状态。可以用来合并多个state变化,减少state变化引起render的次数

import { useReducer } from "react";

function reducer(state, action) {
  return action.type === "update"
    ? {
        ...state,
        ...action.payload
      }
    : {
        ...state
      };
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, {
    name: "app",
    count: 0
  });

  return (
    <div>
      当前count值为:{state.count}
      <br />
      <span
        onClick={() => {
          dispatch({ type: "update", payload: { count: state.count + 1 } });
        }}
      >
        点击修改count值
      </span>
    </div>
  );
}

8. useLayoutEffect

在组件即将渲染到界面上时执行,依赖影响同useEffect

9. useImperativeHandle

搭配「forwardRef」使用。可以让父组件获取子组件的真实节点

import { useRef, useImperativeHandle, forwardRef, useEffect } from "react";

function Test(props, ref) {
  const mRef = useRef(null);
  useImperativeHandle(ref, () => mRef.current);
  return <div ref={mRef}> I'm test component</div>;
}

const TestRef = forwardRef(Test);
export default function App() {
  const ref = useRef(null);
  useEffect(() => {
    console.log(ref.current.textContent, "this is app log");
  }, []);
  return <TestRef ref={ref} />;
}
posted @   酉云良  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示