简体   繁体   English

React forwardRef - 在组件和父组件中访问 ref

[英]React forwardRef - access ref within component, and in parent

I need to access the ref to a textarea inside a component.我需要访问组件内文本区域的引用。 Within the component, its easy enough:在组件中,它很简单:

const MyComponent = () => {
  const inputRef = useRef();

  return <textarea ref={inputRef} />
}

Now the ref is available within MyComponent and I can use it for some internal logic.现在 ref 在 MyComponent 中可用,我可以将它用于一些内部逻辑。

There are cases where I need to access the ref from the parent component as well.在某些情况下,我还需要从父组件访问 ref。 In that case, I can use forwardRef:在这种情况下,我可以使用 forwardRef:

const MyComponent = React.forwardRef((props, ref) => {
  return <textarea ref={ref} />
})

// In some parent
const MyParent = () => {
  const inputRefFromParent = useRef();
  return <MyComponent ref={inputRefFromParent} />
}

Now I can access to ref of the textarea from the parent component, and use it for logic within the parent component.现在我可以从父组件访问textarea的 ref,并将其用于父组件内的逻辑。

I find myself in a situation where I need to do some internal logic with the ref within MyComponent , but I may also need to get that ref from MyParent .我发现自己处于需要对MyComponent中的 ref 执行一些内部逻辑的情况,但我可能还需要从MyParent获取该 ref。 How can I do this?我怎样才能做到这一点?

You can keep a ref in the MyComponent and expose what you would need in the parent component using useImperativeHandle hook using the ref passed from the MyParent .您可以在MyComponent中保留一个ref ,并使用从MyParent传递的ref使用useImperativeHandle挂钩在父组件中公开您需要的内容。

Try like below.像下面这样尝试。 It exposes the focus method in the textarea to parent.它将文本区域中的焦点方法公开给父级。 And you can do any other internal things with the access to textAreaRef .您可以通过访问textAreaRef来执行任何其他内部操作。

import { useRef, forwardRef, useImperativeHandle } from "react";

const MyComponent = forwardRef((props, ref) => {
  const textAreaRef = useRef();

  // all the functions or values you can expose here
  useImperativeHandle(ref, () => ({
    focus: () => {
      textAreaRef.current.focus();
    }
  }));

  const internalFunction = () => {
    // access textAreaRef
  };

  return <textarea ref={textAreaRef} />;
});

// In some parent
const MyParent = () => {
  const inputRefFromParent = useRef();

  // you can call inputRefFromParent.current.focus(); in this compoenent
  return <MyComponent ref={inputRefFromParent} />;
};

In addition to Amila's answer, I found another way to do it, by using a ref callback :除了 Amila 的回答之外,我还找到了另一种方法,即使用ref 回调

const MyComponent = React.forwardRef((props, parentRef) => {
  const localRef = useRef();
  return <textarea ref={ref => {
    parentRef.current = ref;
    localRef.current = ref;
  }} />
})

So the callback ref keeps finer grain control of the ref to the textarea , and simply assigns its value to both the local ref and the parent ref.因此,回调 ref 对textarea的 ref 进行更细粒度的控制,并简单地将其值分配给本地 ref 和父 ref。

You could do also the following:您还可以执行以下操作:

const MyComponent = React.forwardRef((props, externalRef) => {
    const internalRef = useRef<HTMLElement>();
    const ref = useMemo(
        () => externalRef || internalRef,
        [externalRef, internalRef]
    ) as React.MutableRefObject<HTMLElement>;
    
    return <textarea ref={ref} />
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM