四种情况父组件如何获取子组件值
🧭

四种情况父组件如何获取子组件值

Property
FrontEnd
Year
2022
Author
Tweet
子组件获取父组件的值都知道,最基本的就是通过props传值即可,同样也可以使用context
由于是单向数据流,那么父组件是怎么获取子组件的值呢。
类组件函数组件都进行梳理

均为类组件

使用 ref
import React, { Component } from 'react'; import ChildClass from './ChildClass'; class FatherClass extends Component { constructor(props) { super(props); this.state = {}; this.child = React.createRef(); } getValue = () => { console.log('this.child', this.child); }; render() { return ( <div> <ChildClass ref={this.child} /> <button onClick={this.getValue}>获取输入框内容</button> </div> ); } } export default FatherClass;
import React, { Component } from 'react'; class ChildClass extends Component { constructor(props) { super(props); this.state = { value: '', }; } handleChange = (e) => this.setState({ value: e.target.value }); render() { const { value } = this.state; return ( <div> <input value={value} onChange={this.handleChange} /> </div> ); } } export default ChildClass;
打印的日志如下
notion image
这样就可以获取子组件的所有值

均为函数组件

import React, { useRef } from 'react'; import ChildFun from './ChildFun'; function FatherFun() { const childRef = useRef(); const getValue = () => { console.log('childRef', childRef); }; return ( <div> <ChildFun ref={childRef} /> <button onClick={getValue}>获取输入框内容</button> <button onClick={() => childRef.current?.handleChange('666')}> 父组件修改输入框的值为666 </button> </div> ); } export default FatherFun;
import React, { useState, forwardRef, useImperativeHandle } from 'react'; function ChildFun(props, ref) { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; useImperativeHandle(ref, () => ({ value, handleChange: (res) => setValue(res) })); return ( <div> <input value={value} onChange={handleChange} /> </div> ); } export default forwardRef(ChildFun);
打印的日志如下
notion image
与类组件不同的是
  1. 父组件使用 useRef 创建 ref
  1. 子组件需要使用 useImperativeHandleforwardRef
  1. useImperativeHandle可以在使用 ref 时自定义暴露给父组件的实例值 (也就是说只有valuehandleChange 会暴露给父组件,组件其他的内容不会暴露给父组件)

父组件是类组件,子组件是函数组件

这种方式很常见,只需将上面代码中 FatherClassChildFun 这两个组件组合即可
import React, { Component } from 'react'; import ChildFun from './ChildFun'; class FatherClass extends Component { constructor(props) { super(props); this.state = {}; this.child = React.createRef(); } getValue = () => { console.log('this.child', this.child); }; render() { return ( <div> <ChildFun ref={this.child} /> <button onClick={this.getValue}>获取输入框内容</button> <button onClick={() => this.child.current?.handleChange('666')}> 父组件修改输入框的值为666 </button> </div> ); } } export default FatherClass;
import React, { useState, forwardRef, useImperativeHandle } from 'react'; function ChildFun(props, ref) { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; useImperativeHandle(ref, () => ({ value, handleChange: (res) => setValue(res) })); return ( <div> <input value={value} onChange={handleChange} /> </div> ); } export default forwardRef(ChildFun);
打印的日志如下
notion image

父组件是函数组件,子组件是类组件

import React, { useRef } from 'react'; import ChildClass from './ChildClass'; function FatherFun() { const childRef = useRef(); const getValue = () => { console.log('childRef', childRef); }; return ( <div> <ChildClass ref={childRef} /> <button onClick={getValue}>获取输入框内容</button> <button onClick={() => childRef.current?.customChange('666')}> 父组件修改输入框的值为666 </button> </div> ); } export default FatherFun;
import React, { Component } from 'react'; class ChildClass extends Component { constructor(props) { super(props); this.state = { value: '', }; } customChange = (res) => { this.setState({ value: res, }); }; handleChange = (e) => this.setState({ value: e.target.value }); render() { const { value } = this.state; return ( <div> <input value={value} onChange={this.handleChange} /> </div> ); } } export default ChildClass;
✍️
四种情况:父组件获取子组件值