I am trying to use functional components with hooks in 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.
What I am trying to do is modify an SVG file I am loading when the user does something.
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:
<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.
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?
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.
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
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:
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:
const appleRef = useRef(null);
useEffect(() => {
if (appleRef.current !== null) {
console.log(appleRef.current);
}
}, []);
I recommend reading more about useRef
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.