简体   繁体   English

如何在功能组件中正确使用 forwardRef?

[英]How to use forwardRef correctly in a functional component?

I am trying to use functional components with hooks in React.我正在尝试在 React 中使用带有钩子的功能组件。 I've used plenty of class components, but it seems like functional components are the new pattern for React, so I'm trying to make them work.我使用了大量的类组件,但似乎函数式组件是 React 的新模式,所以我正在努力让它们工作。

What I am trying to do is modify an SVG file I am loading when the user does something.我想要做的是修改我在用户执行某些操作时加载的 SVG 文件。

Here's the basics of my code:这是我的代码的基础知识:

function home() {

const appleRef = useRef({ value: null });

  useEffect(() => {
    if (typeof appleRef !== "undefined") {
      console.log(appleRef);
    }
  }, []);

return(
          <DiApple
            ref={appleRef}
            size={"3rem"}
            color={"black"}
            className="mi-home-card-icon mi-home-card-icon-apple"
          />
)
}

Which turns into this in the DOM:这在 DOM 中变成了这样:

<svg stroke="currentColor" fill="currentColor" stroke-width="0" version="1.1" viewBox="0 0 32 32" color="black" class="mi-home-card-icon mi-home-card-icon-apple" height="3rem" width="3rem" xmlns="http://www.w3.org/2000/svg" style="color: black;"><path d="M23.023 17.093c-0.033-3.259 2.657-4.822 2.777-4.901-1.512-2.211-3.867-2.514-4.705-2.548-2.002-0.204-3.91 1.18-4.926 1.18-1.014 0-2.583-1.15-4.244-1.121-2.185 0.033-4.199 1.271-5.323 3.227-2.269 3.936-0.58 9.769 1.631 12.963 1.081 1.561 2.37 3.318 4.061 3.254 1.63-0.064 2.245-1.055 4.215-1.055s2.524 1.055 4.248 1.021c1.753-0.032 2.864-1.591 3.936-3.159 1.24-1.814 1.751-3.57 1.782-3.659-0.038-0.017-3.416-1.312-3.451-5.202zM19.783 7.53c0.897-1.089 1.504-2.602 1.34-4.108-1.294 0.053-2.861 0.86-3.79 1.948-0.832 0.965-1.561 2.502-1.365 3.981 1.444 0.112 2.916-0.734 3.816-1.821z"></path></svg>

I want to be able to modify this SVG information on the user interacting with certain other DOM elements.我希望能够在用户与某些其他 DOM 元素交互时修改此 SVG 信息。

When I try to use this, I get the error:当我尝试使用它时,出现错误:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Which from what I'm reading, I need to also add a forwardRef, because React needs it to be a component for some reason?从我正在阅读的内容来看,我还需要添加一个 forwardRef,因为 React 出于某种原因需要它成为一个组件?

I'm not totally understanding the exact process here.我不完全理解这里的确切过程。

If someone could explain to me what my code should look like to be able to affect the SVG, as well as what exactly forwardRef is doing here and how it differs from class components, that would be massively helpful to me.如果有人可以向我解释我的代码应该是什么样子才能影响 SVG,以及 forwardRef 在这里做什么以及它与类组件有何不同,那将对我非常有帮助。

import React, { useEffect, useRef } from "react";
function Home() {
const appleRef = useRef({ value: null });//remove this ref
const svgRef = React.createRef();
const DiApple = React.forwardRef((props, ref) => {
  return (
    <svg
      ref={ref}
      stroke="currentColor"
      fill="currentColor"
      strokeWidth="0"
      version="1.1"
      viewBox="0 0 32 32"
      color="black"
      className="mi-home-card-icon mi-home-card-icon-apple"
      height="3rem"
      width="3rem"
      xmlns="http://www.w3.org/2000/svg"
      style={{ color: "black" }}
      {...props}
    >
      <path d="M23.023 17.093c-0.033-3.259 2.657-4.822 2.777-4.901-1.512-2.211-3.867- 2.514-4.705-2.548-2.002-0.204-3.91 1.18-4.926 1.18-1.014 0-2.583-1.15-4.244-1.121-2.185 0.033-4.199 1.271-5.323 3.227-2.269 3.936-0.58 9.769 1.631 12.963 1.081 1.561 2.37 3.318 4.061 3.254 1.63-0.064 2.245-1.055 4.215-1.055s2.524 1.055 4.248 1.021c1.753-0.032 2.864-1.591 3.936-3.159 1.24-1.814 1.751-3.57 1.782-3.659-0.038-0.017-3.416-1.312-3.451-5.202zM19.783 7.53c0.897-1.089 1.504-2.602 1.34-4.108-1.294 0.053-2.861 0.86-3.79 1.948-0.832 0.965-1.561 2.502-1.365 3.981 1.444 0.112 2.916-0.734 3.816-1.821z"></path>
  </svg>
  );
});

return (
  <DiApple
    ref={svgRef}
    size={"3rem"}
    color={"black"}
    className="mi-home-card-icon mi-home-card-icon-apple"
  />
);}

export default Home;

reference to svg is avaliable on the ref object created using React.createRef as follows svgRef.current参照SVG是裁判对象上avaliable使用创建React.createRef如下svgRef.current

DiApple is a function component, and as explained in React documentation about forwarding refs , to define what ref will refer to on DiApple , you need to wrap it in a forwardRef call and pass the ref argument to your desired element: DiApple是一个函数组件,正如 React 文档中关于转发 refs所解释的,要定义ref将在DiAppleDiApple ,您需要将其包装在forwardRef调用中并将ref参数传递给您想要的元素:

const DiApple = React.forwardRef(function DiApple(props, ref) {
  return (
    <svg ref={ref}>
      {/* ... */}
    </svg>
  )
})

Next, I suggest passing null to useRef instead of { value: null } , that way appleRef.current will initially be null , then it will refer to the DOM node:接下来,我建议将null传递给useRef而不是{ value: null } ,这样appleRef.current最初将是null ,然后它将引用 DOM 节点:

const appleRef = useRef(null);

useEffect(() => {
  if (appleRef.current !== null) {
    console.log(appleRef.current);
  }
}, []);

I recommend reading more about useRef .我建议阅读有关useRef更多信息。

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

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