React中父组件读取子组件的属性的方法
1. 【通过ref】父组件创建ref绑定到子组件并通过forwardRef将父组件的中ref绑定到子组件中具体的DOM元素进而操作。eg: 父组件的ref绑定到子组件的input框上
2. 【通过useImperativeHandle】ref + forwardRef + useImperativeHandle获取子组件中暴露的属性或方法
3. 【回调函数传递属性】props + 回调的方式获取子组件中属性
4. 【状态提升】通过状态提升,完全将子组件中的属性和方法交由父组件
方法 1: 通过 ref 获取子组件实例或 DOM 节点
import React, { forwardRef, useRef } from 'react';
const Child = forwardRef((props, ref) => {
return <input ref={ref} placeholder="子组件输入框" />;
});
const Parent = () => {
const inputRef = useRef();
const handleClick = () => {
console.log(inputRef.current.value); // 获取子组件 input 的值
};
return (
<div>
<Child ref={inputRef} />
<button onClick={handleClick}>读取子组件值</button>
</div>
);
};
export default Parent;
方法2:通过useImperativeHandle自定义暴露子组件中属性和行为
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
const Child = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
getValue: () => inputRef.current.value,
clear: () => {
inputRef.current.value = '';
},
}));
return <input ref={inputRef} placeholder="子组件输入框" />;
});
const Parent = () => {
const childRef = useRef();
const handleGetValue = () => {
console.log(childRef.current.getValue()); // 调用子组件自定义方法获取值
};
const handleClear = () => {
childRef.current.clear(); // 调用子组件自定义方法清空值
};
return (
<div>
<Child ref={childRef} />
<button onClick={handleGetValue}>获取值</button>
<button onClick={handleClear}>清空值</button>
</div>
);
};
export default Parent;
方法3:通过props和子组件回调向父组件暴露属性或行为
import React, { useState } from 'react';
const Child = ({ onExpose }) => {
const [value, setValue] = useState('');
React.useEffect(() => {
if (onExpose) {
onExpose({ value, setValue }); // 暴露子组件的状态和修改方法
}
}, [onExpose, value]);
return <input value={value} onChange={(e) => setValue(e.target.value)} />;
};
const Parent = () => {
const [childState, setChildState] = useState(null);
const handleExpose = (exposed) => {
setChildState(exposed);
};
const handleRead = () => {
console.log(childState?.value); // 获取子组件的值
};
const handleModify = () => {
childState?.setValue('修改后的值'); // 修改子组件的值
};
return (
<div>
<Child onExpose={handleExpose} />
<button onClick={handleRead}>读取子组件值</button>
<button onClick={handleModify}>修改子组件值</button>
</div>
);
};
export default Parent;
方法4:子组件的属性和行为完全交由父组件进行管理
import React, { useState } from 'react';
const Child = ({ onExpose }) => {
const [value, setValue] = useState('');
React.useEffect(() => {
if (onExpose) {
onExpose({ value, setValue }); // 暴露子组件的状态和修改方法
}
}, [onExpose, value]);
return <input value={value} onChange={(e) => setValue(e.target.value)} />;
};
const Parent = () => {
const [childState, setChildState] = useState(null);
const handleExpose = (exposed) => {
setChildState(exposed);
};
const handleRead = () => {
console.log(childState?.value); // 获取子组件的值
};
const handleModify = () => {
childState?.setValue('修改后的值'); // 修改子组件的值
};
return (
<div>
<Child onExpose={handleExpose} />
<button onClick={handleRead}>读取子组件值</button>
<button onClick={handleModify}>修改子组件值</button>
</div>
);
};
export default Parent;
学而不思则罔,思而不学则殆!