React 前端导航

React 父组件如何调用子组件方法

React 父组件如何调用子组件方法

子组件是类组件,使用 Refs

使用 React.createRef() 创建 Refs, Refs 可以通过 ref 属性附加到元素节点,我们就可以通过 ref.current 访问被附加的元素节点。

例如:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <input ref={this.myRef} />;
  }
}

在上面的例子中,我们可以通过 myRef.current 访问到 input 节点,从而可以调用input上诸如 focus 等方法。

不同的元素类型会导致 ref 的值不同:
① 当 ref 附加的元素是 HTML 元素时,ref.current 指向的是底层的DOM元素。
② 当 ref 附加的元素是 class 组件时,ref.current 指向 class 组件实例。

注:默认情况下,不能在函数组上使用 ref 属性, 因为他们没有实例。但结合 forwardRef 方法我们就可以在函数组件上使用 ref,后面会介绍。

子组件是函数组件,使用 Refs 转发

① 使用 forwardRef 转发 Refs 到 DOM 组件,就是将 父组件的 ref 向下传递给子组件。

例如:

function Farther = ()= {
 const ref = useRef(null);

 return <ChildB ref={ref} />
};

const ChildB = React.forwardRef(ChildA);

function ChildA = (pops,ref) => {
  return <input ref={ref} />
};

上面的例子中,父组件 Father 就能通过 ref.current 访问子组件 ChildA 中的 input 元素。

注:ChildA 子组件的第二个参数只在使用 React.createRef 定义时存在,常规的函数组件和 class 组件都是不接受 ref 参数的,而且 Props 中也不存在 ref 。转发的 ref 也只能附加的 HTML 元素 或 class 组件实例

② forwardRef 结合 useImperativeHandle 使用,自定义暴露给父组件的实例值。

useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。

例如:

function Farther = ()= {
 const ref = useRef(null);

 return <ChildB ref={ref} />
};

const ChildB = React.forwardRef(ChildA);

function ChildA = (pops,ref) => {
  useImperativeHandle(ref,()=({
    name: "ChildA"
    log: log,
  }));
  const log = ()=>{
    console.log("子组件内部log")
  }
  return <input />
};

上面的例子中,父组件 Father 拿到的 ref.current 的值就是对象 {name:"ChildA",log:log}, 父组件也能通过 ref.current.log 调用子组件的 log 方法。

③ 在高阶组件(HOC)中转发 Refs

高阶组件是参数为组件,返回值为新组件的函数。

虽然高阶组件的约定是将所有 props 传递给被包装组件,但这对于 refs 并不适用。那是因为 ref 实际上并不是一个 prop - 就像 key 一样,它是由 React 专门处理的。如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。

我们可以在 HOC 中使用自定义的 prop 属性接收 ref 并传递给 子组件.

例如:

function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;

      // 将自定义的 prop 属性 “forwardedRef” 定义为 ref
      return <Component ref={forwardedRef} {...rest} />;
    }
  }

  // 注意 React.forwardRef 回调的第二个参数 “ref”。
  // 我们可以将其作为常规 prop 属性传递给 LogProps,例如 “forwardedRef”
  // 然后它就可以被挂载到被 LogProps 包裹的子组件上。
  return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/27

#react#refs

相关推荐

react中实现markdown文件读取展示

react中实现markdown文件读取展示

umi实践问题汇总--持续更新

在使用umi的过程中所遇到问题的记录汇总