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} />;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异