如何子传父?
可以结合useRef和forwardRef以及useImperativeHandle的方式,子组件暴露出ref实例,通过命令式的方式传递。
但是这样会让状态变的非常乱,不如直接声明式的useState()
js
// 子组件:ImperativeInput.jsx
import React, { useState, useImperativeHandle, forwardRef, useRef } from 'react';
// 1. 使用 forwardRef 包裹组件,接收第二个参数 ref
const ImperativeInput = forwardRef((props, ref) => {
const [value, setValue] = useState('');
const inputRef = useRef(); // 用于操作真实的DOM
// 3. 使用 useImperativeHandle 自定义暴露给父组件的 ref.current
useImperativeHandle(ref, () => ({
// 这里返回的对象,就是父组件 ref.current 的值
reset: () => {
setValue('');
console.log('子组件的 reset 方法被调用');
},
focus: () => {
inputRef.current.focus();
}
}));
return (
<input
ref={inputRef}
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="请输入内容..."
/>
);
});
export default ImperativeInput;
// 父组件:Form.jsx
import React, { useRef } from 'react';
import ImperativeInput from './ImperativeInput';
function Form() {
// 2. 在父组件中创建 ref
const inputRef = useRef(null);
const handleReset = () => {
// 4. 通过 ref.current 调用子组件暴露的方法
if (inputRef.current) {
inputRef.current.reset();
inputRef.current.focus();
}
};
return (
<div>
{/* 将 ref 传递给子组件 */}
<ImperativeInput ref={inputRef} />
<button onClick={handleReset}>重置并聚焦</button>
</div>
);
}