react 内置hook api使用详情
1,useState
1,返回一个state,以及更新state的函数
2,在初始渲染期间,返回的状态(state)与传入的第一个参数(initialState)值相同
3,setState函数用于更新state,它接受一个新的state值,并将组件的一次重新渲染加入队列
4,后续重新渲染中,useState返回的第一个值始终是更新后最新的state
5,initialState 只在初始渲染时起作用,它也可以写成函数
const [state, setState] = useState(initialState);
const [state, setState] = useState(() => {
.....
return initialState
});
setState有2种用法
// 第一种
setState(newData)
// 第二种
setState(prevData => data + 1)
2,useEffect
1,该 Hook 接收一个包含命令式、且可能有副作用代码的函数。
2,组件创建 与 组件更新都会执行
3,如果只想执行一次,可以第二个参数传空数组
4,当第二个参数有值,不是一个空数组,将会监听该参数的变化,有变化将会执行函数
5,存在三种写法,相容点:在组件挂载和组件卸载前都会执行
第一种: 所有state数据改变都会执行
useEffect(() => {
...
// 存在返回函数,该函数将在组件卸载前执行
return () => {}
});
第二种: 只在组件挂载和组件卸载前执行
userEffect(() => {
...
// 存在返回函数,该函数将在组件卸载前执行
return () => {}
}, [])
第三种:依赖数据发生改变执行
useEffect(() => {
// 存在返回函数,该函数将在组件卸载前执行
return () => {}
}, [a, b]) // a,b为依赖数据
3,useLayoutEffect
1,该函数与useEffect相同,但是它会在所有DOM变更后同步调用effect
2,可以使用它来读取浏览器布局并同步触发重渲染
3,在浏览器执行绘制之前,useLayoutEffect内部的更新计划将同步刷新。
useLayoutEffect(() =>{})
4,useContext
接收一个context对象,当组件上层的MyContext.provider的值变化时,useContext会触发重渲染,并使用最新的context value值
const MyContext = createContext()
<MyContext.provider value={count}></MyContext.provider>
const value = useContext(MyContext);
5,useReducer
useState的替代方案
参数一:它接收一个形如 (state, action) => newState 的 reducer 回调函数,返回最新的state值
参数二:初始state值
参数三:一个函数,处理初始的state值,将改函数返回的值作为初始值
// 使用
const [state, dispatch] = useReducer(reducer, initialArg, init);
// 例子:
function init(initialCount) { return {count: initialCount};}
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
case 'reset': return init(action.payload); default:
throw new Error();
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, initialCount, init);
return (
<>
Count: {state.count}
<button
onClick={() => dispatch({type: 'reset', payload: initialCount})}>
Reset
</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
// }
6,useCallback
当依赖的state值发生改变时,将会执行回调函数。
参数一:回调函数
参数二(array):hook依赖的state
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
7,useMemo
当依赖的state值发生改变时,将会执行回调函数返回memoize值
注意:当没有提供依赖项数组,每次渲染都会计算新值
const memoizedValue = useMemo(() => computeValue(a, b), [a, b]);
8,useRef
1,返回一个可变的ref对象
2,其.current属性被初始化为传入的参数
3,返回的ref对象在组件的整个生命周期内保持不变
4,它和普通js对象的区别是,每次渲染时都会返回同一个ref对象
const refContainer = useRef(initialValue);
9,useImperativeHandle(配合forwardRef)
useImperativeHandle:自定义暴露给父组件的实例值
--- 第一个参数为父组件传递的 ref
--- 第二个参数是一个函数,返回的一个对象会自动绑定到ref上
--- 第三个参数是函数依赖的值(可选)
forwardRef:创建一个Rect组件,能够将接收的ref属性转发到其组件树下的另一个组件中
配合useRef、forwardRef使用
// 父组件
function App() {
const inputRef = useRef();
const getClick = () => {
inputRef.current.focus();
}
return(<>
<children />
<button onClick={getClick()}>点击调用子组件暴露给父组件的方法</button>
</>)
})
// 子组件
const children = forwardRef(function(props, ref){
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}))
return <>
<input type="text" ref={inputRef} />
</>
})
10,useDebugValue
可用于在 React 开发者工具中显示自定义 hook 的标签。
useDebugValue(value)
// 例:自定义hook
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
// ...
// 在开发者工具中的这个 Hook 旁边显示标签 // e.g. "FriendStatus: Online"
useDebugValue(isOnline ? 'Online' : 'Offline');
return isOnline;
}
11,useDeferredValue
返回的值延迟更新,与防抖和节流类似
const deferredValue = useDeferredValue(value);
// 例:
function Typeahead() {
const query = useSearchQuery('');
const deferredQuery = useDeferredValue(query);
const suggestions = useMemo(() =>
<SearchSuggestions query={deferredQuery} />,
[deferredQuery]
);
return (
<>
<SearchInput query={query} />
<Suspense fallback="Loading results...">
{suggestions}
</Suspense>
</>
);
}
12,useTransition
返回一个状态值标识过渡任务的等待状态,以及一个启动该过渡任务的函数
// 使用
const [isPending, startTransition] = useTransition();
// 例:
function App() {
const [isPending, startTransition] = useTransition();
const [count, setCount] = useState(0);
function handleClick() {
//1, 可以将提供的回调函数作为一个过渡任务
startTransition(() => {
setCount(c => c + 1);
})
//2, 直接执行
startTransition()
}
return (
<div>
{isPending && <Spinner />}
<button onClick={handleClick}>{count}</button>
</div>
);
}
13,useId
生成跨服务端和客户端的稳定唯一ID
生成一个包含:的字符串token
有助于却表token是唯一的
在css选择器或querySelectorAll等api中不受支持
useId支持identifierPrefix以防止在多个根应用的程序中发生冲突
const id = useId();