子组件获取父组件的值都知道,最基本的就是通过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;
打印的日志如下
这样就可以获取子组件的所有值
均为函数组件
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);
打印的日志如下
与类组件不同的是
- 父组件使用
useRef
创建ref
- 子组件需要使用
useImperativeHandle
,forwardRef
。
-
useImperativeHandle
可以在使用ref
时自定义暴露给父组件的实例值 (也就是说只有value
,handleChange
会暴露给父组件,组件其他的内容不会暴露给父组件)
父组件是类组件,子组件是函数组件
这种方式很常见,只需将上面代码中
FatherClass
与 ChildFun
这两个组件组合即可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);
打印的日志如下
父组件是函数组件,子组件是类组件
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;
四种情况:父组件获取子组件值