一、父子组件都是函数式组件
// 父组件
import React, {useState, useRef } from 'react';
import ClassChild from './classChild'; // 类子组件
const Container = () => {
const cref = useRef()
const [value, setValue] = useState('')
const changeValue = (e) => {
console.log(cref.current) // 取到子组件中的属性
}
return (
<div>
<h1 onClick={changeValue}>test</h1>
<ClassChild ref={cref} />
</div>
)
}
export default Container;
// 子组件
import React, { useState, useImperativeHandle, forwardRef } from 'react';
const Container = (props, ref) => {
let [data,setData] = useState(12);
const changeValue = (e) => {
console.log(data);
}
useImperativeHandle(ref, () => ({
changeValue,
}))
return (
<div>
<h1 onClick={changeValue}>test{data}</h1>
</div>
)
}
export default forwardRef(Container);
二、父组件是类组件、子组件是函数式组件
这种情况时:
父组件正常创建ref, 子组件接收时有所变动
// 父组件
constructor() {
super();
this.containerRef = React.createRef()
}
const test = () => {
console.log(this.containerRef)
this.containerRef.current.handleClear()
console.log(this.containerRef.current.inputValue)
}
render() {
<div>
<button onClick={this.test}>test</button>
<Container ref={this.containerRef} />
</div>
}
// 子组件
// 利用useImperativeHandle、forwardRef 两个hooks钩子来接收绑定
import React, {useState, useRef, useImperativeHandle, forwardRef } from 'react';
const Container = (props,ref) => {
const cref = useRef()
const [value, setValue] = useState('')
const handleClear = () => {
console.log('handle clear')
}
useImperativeHandle(ref, () => ({
handleClear,
inputValue: cref.current.value
}))
const changeValue = (e) => {
setValue(e.target.value)
}
return (
<div>
<h1>test</h1>
<input ref={cref} value = {value} onChange={changeValue}></input>
</div>
)
}
export default forwardRef(Container);
三、父组件是函数式组件、子组件是类组件
这种情况只需要处理父组件就可以,子组件不需要处理
父组件:
import React, {useState, useRef } from 'react';
import ClassChild from './classChild'; // 类子组件
const Container = () => {
const cref = useRef()
const [value, setValue] = useState('')
const changeValue = (e) => {
console.log(cref.current) // 取到子组件中的属性
}
return (
<div>
<h1 onClick={changeValue}>test</h1>
<ClassChild ref={cref} />
</div>
)
}
export default Container;
四、父子组件都是函数式组件:
constructor() {
super();
this.containerRef = React.createRef()
}
const test = () => {
console.log(this.containerRef)
this.containerRef.current.handleClear()
console.log(this.containerRef.current.inputValue)
}
render() {
<div>
<button onClick={this.test}>test</button>
<Container onRef={(ref) => {this.containerRef = ref}} />
</div>
}
// 子组件
// 将子组件的this 传回去
componentDidMount() {
this.props.onRef(this)
}
总结来说:
函数式组件作为子组件的时候需要借助两个钩子来处理, 即useImperativeHandle, forwardRef
函数式组件作为父组件的时候需要借助钩子 useRef