在React中,开发一个自定义Hook来管理组件的焦点状态通常涉及使用useRef
来存储对DOM元素的引用,并可能包括在特定条件下自动聚焦元素的功能。同时,我们也可以通过回调Refs的方式来传递Ref到子组件中,尤其是在你需要管理那些不是直接渲染的DOM元素的焦点时。下面是如何实现这样一个自定义Hook的例子,同时确保类型安全:
文末有我帮助400多位同学成功领取到前端offer的面试综合题哦,包含了工程化,场景题,八股文,简历模板,等等
自定义Hook: useFocusManagement
首先,我们定义一个自定义Hook useFocusManagement
,它将处理聚焦逻辑,并允许外部通过回调Refs传递或获取DOM元素的引用。
import { useState, useEffect, useRef, RefCallback } from 'react';
type FocusManagementOptions = {
shouldFocus?: boolean;
focusOnMount?: boolean;
};
function useFocusManagement(options: FocusManagementOptions = {}) {
const { shouldFocus = true, focusOnMount = true } = options;
const [isFocused, setIsFocused] = useState(false);
const focusRef = useRef<HTMLElement | null>(null);
// 用于设置Ref的回调函数,确保类型安全
const setFocusRef: RefCallback<HTMLElement> = (element) => {
focusRef.current = element;
if (focusOnMount && shouldFocus && element) {
element.focus();
}
};
useEffect(() => {
if (shouldFocus && focusRef.current) {
focusRef.current.focus();
setIsFocused(true);
}
}, [shouldFocus]);
// 提供给外部控制聚焦状态的方法
const triggerFocus = () => {
if (focusRef.current) {
focusRef.current.focus();
setIsFocused(true);
}
};
// 返回聚焦Ref、当前焦点状态及聚焦方法
return { focusRef: setFocusRef, isFocused, triggerFocus };
}
使用自定义Hook
接下来,我们演示如何在一个组件中使用这个Hook。假设我们有一个InputComponent
,我们想在某些条件下自动聚焦它。
import React from 'react';
import useFocusManagement from './useFocusManagement';
interface InputProps {
autoFocusOnCondition?: boolean;
}
const InputComponent: React.FC<InputProps> = ({ autoFocusOnCondition }) => {
const { focusRef, isFocused, triggerFocus } = useFocusManagement({
shouldFocus: autoFocusOnCondition,
focusOnMount: autoFocusOnCondition,
});
return (
<div>
<input ref={focusRef} placeholder="Type something..." />
{isFocused ? <span>Input is focused.</span> : <span>Input is not focused.</span>}
<button onClick={triggerFocus}>Focus Input</button>
</div>
);
};
export default InputComponent;
在这个例子中,useFocusManagement
Hook接收一个选项对象,允许用户控制是否应该聚焦以及是否在挂载时自动聚焦。它返回一个Ref回调函数(setFocusRef
),可以用来绑定到需要管理焦点的DOM元素上,同时提供了一个isFocused
状态和triggerFocus
方法来手动触发聚焦操作。
注意,通过使用RefCallback<HTMLElement>
类型,我们确保了传递给ref
属性的回调函数期望接收一个HTMLElement
类型的参数,从而实现了类型安全。同时,自定义Hook内部的状态管理也保证了对外部组件而言,聚焦逻辑是透明且易于使用的。
堪称2024最强的前端面试场景题,已帮助432人成功拿到offer