面试题答案
一键面试1. useImperativeHandle 和 forwardRef 的关系
forwardRef
是 React 提供的一个函数,用于转发 ref 到子组件。它允许我们将父组件的 ref 传递给子组件内部的 DOM 元素或另一个 React 组件,这样父组件就可以直接操作子组件的实例。useImperativeHandle
是 React Hook,它用于在使用forwardRef
时自定义暴露给父组件的实例值。通过useImperativeHandle
,我们可以精确控制父组件通过 ref 能访问到子组件的哪些方法和属性,而不是直接暴露子组件的整个实例。
2. 复杂场景
在需要父组件直接调用子组件特定方法,同时又要对子组件内部实现细节进行封装的场景下会同时使用它们。例如,开发可复用的表单组件,父组件需要触发子组件的表单验证,但子组件内部有自己的状态管理和其他复杂逻辑,不希望父组件直接访问所有内部状态和方法,只希望暴露验证方法给父组件。
3. 代码示例
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
// 子组件,一个可复用的表单组件
const FormComponent = forwardRef((props, ref) => {
const inputRef = useRef(null);
// 表单验证方法
const validateForm = () => {
if (inputRef.current.value) {
return true;
}
return false;
};
// 使用 useImperativeHandle 自定义暴露给父组件的实例值
useImperativeHandle(ref, () => ({
validate: validateForm
}));
return (
<form>
<input ref={inputRef} type="text" />
</form>
);
});
// 父组件
const ParentComponent = () => {
const formRef = useRef(null);
const handleClick = () => {
if (formRef.current) {
const isValid = formRef.current.validate();
if (isValid) {
console.log('表单验证通过');
} else {
console.log('表单验证失败');
}
}
};
return (
<div>
<FormComponent ref={formRef} />
<button onClick={handleClick}>验证表单</button>
</div>
);
};
export default ParentComponent;
在上述代码中,FormComponent
使用 forwardRef
接收父组件传递的 ref
,并在内部使用 useImperativeHandle
自定义暴露给父组件的方法 validate
,父组件通过 ref
调用子组件的 validate
方法来进行表单验证。