react父子组件传值之二,ref传值(父组件调用子组件的值和方法) useRef+useImperativeHandle(hook)

父组件

import React, {
  useState,
  useRef,
} from 'react';
import Counter from './four';
import CounterTwo from './five';
export function Three(props) {
  // 获取子组件实例
  const childRef = useRef();
  const childRefFive = useRef();
  const [fval, setFval] = useState()
  const [fourval, setFourval] = useState('我是你爸爸')
  // 调用子组件的onChange方法
  const onClickChange = () => {
    console.log('childRef', childRef)
    console.log('childRefFive', childRefFive)
    setFval(childRefFive.current.value)
    childRef.current.toparent(fourval);
    // childRef.current.onChange();
  };

  return (
    <div>
      <h2>父组件</h2>
      <div>{fval}</div>
      <button onClick={onClickChange}>我是子组件</button>
      <Counter ref={childRef} />
      <CounterTwo ref={childRefFive} />
    </div>
  );
}
Counter子组件
import React, {
  useState,
  useRef,
  useImperativeHandle,
  forwardRef,
} from 'react';
const Counter = forwardRef((props, ref) => {

  const [value, setValue] = useState("我是four子组件");
  // 自定义暴露给父组件的实例值 (useImperativeHandle 要配合 forwardRef使用)
  useImperativeHandle(ref, () => ({
    // 暴露函数给父组件调用
    value,
    toparent,
    // 也可以暴露子组件的状态值给父组件使用
  }));
  const toparent = (val) => {
    console.log('value4', value, val)
    setValue(val)
  }
  return (
    <div>
      {value}
      {/* <button onClick={() => toparent()}>我是子组件</button> */}
      <button onClick={toparent}>我是four</button>
    </div>
  )
})
export default Counter
CounterTwo子组件
import React, {
  useState,
  useRef,
  useImperativeHandle,
  forwardRef,
} from 'react';
const Counter = forwardRef((props, ref) => {

  const [value, setValue] = useState("我是five子组件");
  // 自定义暴露给父组件的实例值 (useImperativeHandle 要配合 forwardRef使用)
  useImperativeHandle(ref, () => ({
    // 暴露函数给父组件调用
    value,
    toparent,
    // 也可以暴露子组件的状态值给父组件使用
  }));
  const toparent = (val) => {
    console.log('value5', value, val)
  }
  return (
    <div>
      {value}
      {/* <button onClick={() => toparent()}>我是子组件</button> */}
      <button onClick={toparent}>我是four</button>
    </div>
  )
})
export default Counter

总结:父组件用useRef返回一个可变的 ref 对象,

子组件必须用useImperativeHandle 要配合 forwardRef使用

上一篇:React useState和useReducer不同的应用场景思考


下一篇:自定义树形穿梭框组件