preface
Because React’s functional components are easy to use (as opposed to the Class component), I’ll focus on using functional components to run development. In this blog series, I’m going to share what I’ve learned about the Hook apis. The Hooks series includes the following:
- useState
- useReducer
- useContext
- useEffect
- useMemo
- useRef
- Customize the Hook
What is useRef
UseRef returns a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The ref object returned remains constant throughout the life of the component.
This ref object has only one current property, so you save something inside, and its address stays the same.
A simple example
import React, { useRef } from "react";
export default function App() {
const r = useRef(0);
console.log(r);
const add = () = > {
r.current += 1;
console.log(`r.current:${r.current}`);
};
return (
<div className="App">
<h1>R current: {r.c urrent}</h1>
<button onClick={add}>Click on the + 1</button>
</div>
);
}
Copy the code
I set an R on top to save the result of useRef and log it out, so let’s see what’s inside
> {current: 0}
Copy the code
Inside is acurrent
Property that holds the 0 that I passed in.
UseRef changes do not actively render the page
Let’s click on the button at the topcurrent
+1, you can see that the page is not actively rendered, but newcurrent
The value of theta has become 1
Note When the value of the current property changes, the page does not change as useState or useReducer does. How do you solve this problem? So let’s get to the bottom of this
summary
- We use the
useCurrent
The incominginitialValue
, it can be concluded that it becomes an inclusioncurrent
Property object,current
The corresponding value of the property isinitialValue
- According to the React documentation, you know that the address of this object does not change from beginning to end
- UseRef changes do not actively render the page
Application to solve
Let’s simulate a ComponentDidUpdate using useRef and useEffect
import React, { useEffect, useRef, useState } from "react";
export default function App() {
const r = useRef(0);
const [n, setN] = useState(0);
useEffect(() = > {
r.current += 1;
if (r.current > 1) {
console.log("r.current:" + r.current);
console.log("n:"+ n); }});return (
<div className="App">
<h1>n:{n}</h1>
<h1>r.current{r.current}</h1>
<button
onClick={()= > {
setN(n + 1);
}}
>
{" "}
+1
</button>
</div>
);
}
Copy the code
Render the result for the first time
When you click the +1 button,You’ll see that the code executes, so that you can implementComponentDidUpdate
Current has changed
In the above code, it can be seen that the current on the page has changed. This is because our state has changed, so the new current has also been rendered.
You can think of react as the mechanism:
There’s a single current, I don’t care.
The state has changed. Update the page. Wait, take this current with you.
So we can manually set current changes to actively trigger page updates by setting an impractical state.
If you are careful, you will see that the rendered value on the page is not the latest current value. The reason for this is that Effect is always executed after Render, when current has just become the latest, and React doesn’t just update the view again for Current. So the page is still old Current. And so that confirms what we started with
UseRef changes do not actively render the page
We don’t normally display current in views, but the above example just wants you to notice the subtle relationship between current changes and views
summary
Since current does not actively render pages, it is best to manually set current to be updated by the view along with a fake state.
Have to say forwardRef
ref
On hook components, you cannot use ref directly, and the official website does not even recommend using ref on class components. But we might use a ref, which is mostly used to pass to a child component and get the DOM of that child component. Here is the official documentation Refs and function components
When to use Refs
Here are a few situations where refs are appropriate:
- Manage focus, text selection or media playback.
- Trigger the forced animation.
- Integrate third-party DOM libraries.
Interpreting official examples
function CustomTextInput(props) {
// textInput must be declared here so that ref can reference it
const textInput = useRef(null);// Create an object containing the current property
console.log(textInput);
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input type="text" ref={textInput} />// Attach to the internal DOM<input type="button" value="Focus the text input" onClick={handleClick} />
</div>
);
}
Copy the code
Note that fowardRef is not used in this example, because ref is not used on child components, but inside function components
We can see that by attaching a REF to a React element, we can retrieve its DOM.
There are two steps
useRef
To create aref
objectref={xx}
hangreact
On the element
Then you can use this element. The official example is to take the element and focus it by clicking the button. We now have a rough idea of how ref is used.
Use ref on child components
The above method cannot be used directly on child components, as you might write
<Child ref={textInput} />
Copy the code
Instead of getting the DOM of the subcomponent, we need to use the forwardRef
function CustomTextInput(props) {
// textInput must be declared here so that ref can reference it
const textInput = useRef(null);
console.log(textInput);
function handleClick() {
textInput.current.focus();
}
return (
<div>
<Child ref={textInput} />//** still uses ref to pass **<input type="button" value="Focus the text input" onClick={handleClick} />
</div>
);
}
const Child = forwardRef((props, ref) = > { See me / / * * * *
return <input type="text" ref={ref} />;//** see if I hang it on the corresponding DOM **
});
Copy the code
Parent = (ref={ref}); parent = (ref={ref}); parent = (ref={ref})
current: <input type=”text”></input>
The DOM element of the child component is retrieved.
summary
We learned from the above example that using ref inside a function component is different from using ref on a child component
- If you want to use it inside a function, just create a post-mount ref attribute to the React element.
- If you want to use it on a child component, you need to use it in addition to the steps above
forwardRef
Wrap the function of the child component, and then pass in the second argumentref
, and finally mountref
You can get the DOM normally.
conclusion
We now know that useRef will generate an object with the current property, which will hold the address unchanged for the entire react rendering life, and we can use it to do some things.
For example, create a global invariant data that simulates ComponentDidUpdate
You can also mount it to the React element and get the ELEMENT’s DOM. (Use refs and subcomponents directly with the forwardRef)
github
Finally, I would like to promote the Github blog that I maintain for a long time
1. From learning to summary, record important knowledge points of the front-end, including in-depth Javascript, HTTP protocol, data structure and algorithm, browser principles, ES6, front-end skills, etc.
2. There is a directory in the README to find relevant knowledge points.
If it is helpful to you, welcome star and follow.
The address is here