前言
10分钟快速过完react中的hook函数,适用于新手,大家可以用npm create vite快速搭建一个react本地环境,在本地跑下代码体验更佳,如果对您有一点帮助,麻烦点个赞哦~
useState
声明一个变量和改变当前变量值的方法
const [state, setState] = useState(null);
例子:
const [userName, setUserName] = useState('小明');
const click = (name) => {
setUserName(name)//小明变为小白
}
return (
<>
<h3>{userName}</h3>
<button onClick={()=>click('小白')}>改变名称</button>
</>
)
注:useState是异步操作
useRef
useRef以同步的方式设置值并返回current对象
inputEl.current可拿到声明值并设置,下面挂载到标签中即可以拿到标签属性
const App = ()=>{
const inputEl = useRef(null);
const name = useRef('小明');
const click = () => {
console.log(name.current);//没有挂载到标签中输出小明
inputEl.current.focus();//获取标签属性设置焦点
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={click}>获取焦点</button>
</>
);
}
注:useRef是同步操作
useEffect
创造react的生命周期
挂载时
useEffect(()=>{
//挂载时执行的回调
},[])
更新时
const [num,setNum] = useState(0);
useEffect(()=>{
console.log(num) //num变化的时候会触发当前回调
},[num])
return (
<>
<h3>{num}</h3>
<button onClick={()=>setNum(num+1)}>增加次数</button>
</>
)
销毁时
函数中返回一个函数(高阶函数)
useEffect(()=>{
//这里执行挂载阶段
return ()=>{
console.log('离开页面时执行销毁阶段')
}
},[])
注:useEffct是同步的,不能用async声明执行异步操作
useContext
作用:根组件数据共享给子组件
使用createContext创建上下文
通过声明上下文AppComponent.provider挂载组件并传入value
import React, { createContext, useContext, useState } from 'react'
// 创造一个上下文
const AppComponent = createContext(null);
//父组件
const Father = () => {
const {age} = useContext(AppComponent)//接收父组件传入的值
return(
<div>
父年龄:{age}
<Child></Child>
</div>
)
}
//子组件
const Child = () => {
const {age,setAge} = useContext(AppComponent)//接收上下文(根组件)传入的值和方法
return(
<div>
子年龄:{age}
<button onClick={()=>{setAge(age+1)}}>年龄+1</button>
</div>
)
}
//根组件
const App = () => {
const [age,setAge] = useState(0)
return(
// 指定上下文使用范围,使用provider传入值和方法给子组件共享使用
<AppComponent.Provider value={{age,setAge}}>
<Father></Father>
</AppComponent.Provider>
)
}
export default App
useReducer
作用:在useState的基础上加入更多的逻辑
const App = ()=>{
const [ number , setNumbner ] = useReducer((state,action)=>{
const { name } = action
/* 根据不同名称修改state值 */
switch(name){
case 'add':
return state + 1
case 'sub':
return state - 1
case 'reset':
return 0
}
return state
},0)
return <div>
当前值:{ number }
<button onClick={()=>setNumbner({ name:'add' })} >增加</button>
<button onClick={()=>setNumbner({ name:'sub' })} >减少</button>
<button onClick={()=>setNumbner({ name:'reset'})} >重置</button>
</div>
}
useMemo
作用:提高性能,当依赖的值不变则不会重复渲染,如果依赖值变则再次渲染。useMemo 返回的是函数运行的结果。
用法:声明后直接调用
const App = ()=>{
const [num,setNum] = useState(0)
const CountCallback = useMemo(() => {
return num + 10
},[num]);//CountCallback返回计算的总数
return <div>
{CountCallback}
<button onClick={()=>{setNum(num+1);}} >设置值+1</button>
</div>
}
memo
作用:防止当前引入组件重复渲染
const App = ()=>{
const [num,setNum] = useState(0)
const CountCallback = useMemo(() => {
return num + 10
},[num]);//CountCallback返回计算的总数
return <div>
{CountCallback}
<button onClick={()=>{setNum(num+1);}} >设置值+1</button>
</div>
}
export default memo(App);
useCallback
作用:提高性能,用于函数,防止函数重复渲染,useCallback 返回的是函数。
用法:声明后函数调用
const App = ()=>{
const [num,setNum] = useState(0)
const CountCallback = useCallback(() => {
return num + 10
},[num]);//CountCallback返回计算的总数
return <div>
{CountCallback()}
<button onClick={()=>{setNum(num+1);}} >设置值+1</button>
</div>
}
两者区别:在于 useMemo 返回的是函数运行的结果, useCallback 返回的是函数
forwardRef
作用:forwardRef会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中,通常配合useImperativeHandle使用,示例结合了useImperativeHandle看下面
useImperativeHandle
配合forwardRef使用,共用ref的值
- 第一个参数:接受
forWardRef传递过来的ref。 - 第二个参数:处理函数,返回值作为暴露给父组件的
ref对象。 - 第三个参数:依赖项
deps,依赖项更改形成新的ref对象。
结合示例
const Child = forwardRef((props, ref) =>{
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();//获取焦点
},
clear: ()=>{
inputRef.current.value = ''//清空数据
}
}));
return <input ref={inputRef} />;
})
const App = ()=>{
const ref = useRef(null)
return (
<>
<Child ref={ref}></Child>
<button onClick={()=>{ref.current.focus()}}>获取焦点</button>
<button onClick={()=>{ref.current.clear()}}>清除数据</button>
</>
)
}
useLayoutEffect
同步执行的useEffect
用法与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
尽可能使用标准的 useEffect 以避免阻塞视觉更新。
useDebugValue
useDebugValue 可用于在 React 开发者工具中显示自定义 hook 的标签。
// 自定义 Hook
const useMyCount = (num) => {
const [ count, setCount ] = useState(0);
// 延迟格式化
useDebugValue(count > num ? '溢出' : '不足', status => {
return status === '溢出' ? 1 : 0;
});
const myCount = () => {
setCount(count + 1);
}
return [ count, myCount ];
}
const App = ()=>{
const [ count, seCount ] = useMyCount(10);
return (
<div>
{count}
<button onClick={() => seCount()}>setCount</button>
</div>
)
}
提示:React官网不推荐你向每个自定义 Hook 使用 useDebugValue,只有自定义 Hook 被复用时才最有意义。
结语
如果你觉得此文对你有一丁点帮助,麻烦点个赞哈,谢谢大家~