The original:
Fullstack React’s Guide to using Refs in React Components
By Yomi Eluwande
Translator: Bo Xuan
When using React, the default way of thinking should be that we don’t force DOM changes, but instead re-render components by passing props. However, there are cases where modifying the DOM is unavoidable.
Refs in React provide a way to access React elements (or DOM nodes) created in the Render () method.
When a parent component needs to interact with a child component, we usually use props to pass the relevant information. However, in some cases, we may need to modify the subitem without re-rendering it with new props. This is where the Refs come in.
When should I use Refs?
We recommend using Refs when:
- With the third party
DOM
Library integration - Trigger imperative animation
- Manage focus, text selection or media playback
The third point can also be understood as using
event
Objects? React is a SyntheticEvent.
The official documentation says: Avoid using
refs
To do anything that can be done with a declarative implementation.
So once we’ve determined that we really should use refs, how do we use them?
Use Refs in React
You can use Refs in a number of ways:
- React.createRef()
- Callback refs
- String refs (obsolete)
- forwarding
refs
(Forwarding refs)
Next, let’s look at each implementation:
React.createRef()
Refs can be created using the react.createref () function and attached to HTML elements in the React component via the ref attribute.
A REF is typically created within a component’s constructor to make it available throughout the component. Such as:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.firstRef = React.createRef();
}
render() {
return <div ref={this.firstRef} />; }}Copy the code
As shown above:
- a
ref
The instance is created in the constructor and assigned tothis.firstRef
- in
render()
Method will be created inside the constructorref
Passed to thediv
Next, let’s look at an example of using refs in the React component.
Focus input using Refs
Here’s another example:
// Ref.js
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<input type="text" ref={this.textInput} />
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput} /> </div> ); }}Copy the code
The sample link
In the code block above, we built a button that, when clicked, automatically focuses the page on the input field.
First, we create a ref instance in the constructor, assign it to this.textinput, and then assign it to the input element via the ref attribute.
<input type="text" ref={this.textInput} />Copy the code
Note that when the ref attribute is used by an HTML element (such as the input element in the current example), the ref created using react.createref () in constructor receives the current value from the underlying DOM element.
[d]
Synthetic Events
This means accessing the DOM value, and we need to write something like this:
this.textInput.current;Copy the code
The second element is a button that automatically focuses on the first input box when clicked. We set the this.focusTextInput function for the onClick property.
<input
type="button"
value="Focus the text input"
onClick={this.focusTextInput}
/>Copy the code
The focusTextInput() function uses JavaScript to build the standard DOM function. The.focus() method focuses the cursor on the text input box.
focusTextInput() {
this.textInput.current.focus();
}Copy the code
Finally, the focusTextInput function is bound in this constructor method:
this.focusTextInput = this.focusTextInput.bind(this);Copy the code
Get the value from ref
In this example, we’ll see how to set the ref attribute for the input box and get the value from ref. The following is an example:
The sample link
In this example, we create an input box to enter values. Then, when the submit button is clicked, we will read this value and print it on the console.
// Ref.js
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
}
handleSubmit = e= > {
e.preventDefault();
console.log(this.textInput.current.value);
};
render() {
// tell React that we want to associate the <input> ref
// with the `textInput` that we created in the constructor
return (
<div>
<form onSubmit={e= > this.handleSubmit(e)}>
<input type="text" ref={this.textInput} />
<button>Submit</button>
</form>
</div>); }}Copy the code
Similarly, we use the react.createref () function to create a ref instance and assign it to the instance variable this.textinput.
In the Render function, we want to read the value of the input field under the form. How do we read this value? By specifying a ref for the input and then reading the value of ref.
<input type="text" ref={this.textInput} />Copy the code
Click the Submit button, and the form element in the above example calls the this.Handlesubmit function through the onSubmit method and prints the information in the input box on the console.
handleSubmit = e= > {
e.preventDefault();
console.log(this.textInput);
};Copy the code
Above, parameters
e
Contains event objects. We use the
e.preventDefault()
To tell the browser that we are processing the clicked submit button and that we do not want the event to “bubble up” (that is, prevent the browser’s default behavior).Another difference in React is that you can’t prevent default behavior by returning false. You must explicitly use preventDefault
In the example above, we printed this.textinput, and you can see a ref object on the console.
> Object {current: HTMLInputElement}Copy the code
Notice that it has a current attribute, HTMLInputElement. This is the input DOM element itself, not the actual value. We must use this. (. Current. The value to obtain the real value of the input tag:
handleSubmit = e= > {
e.preventDefault();
console.log(this.textInput.current.value);
};Copy the code
Using refs is a way to extract values directly from a form: just set the ref to the input tag and extract the value when you need it.
Refs callback
Refs callbacks are another way to use Refs in React. To use ref in this way, we need to set the callback function for the ref property. When we set ref, React calls this function and passes it Element as the first argument.
The sample link
Here’s the code for another example. As in the above example, this code gets the text value of the input tag, but here we use a callback reference:
// Refs.js
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = null;
this.setTextInputRef = element= > {
this.textInput = element;
};
}
handleSubmit = e= > {
e.preventDefault();
console.log(this.textInput.value);
};
render() {
return (
<div>
<form onSubmit={e= > this.handleSubmit(e)}>
<input type="text" ref={this.setTextInputRef} />
<button>Submit</button>
</form>
</div>); }}Copy the code
In the example above, we set the ref for the input tag to this.setTextInputRef.
React passes DOM elements to ref’s callback when the component is installed; When a component is unloaded, NULL is passed. (The REF callback is called before the componentDidMount and componentDidUpdate life cycle.)
String Ref (obsolete)
There is another way of setting refs, but it is considered outdated and may soon be abandoned. But you’ll probably see it in other people’s code, so here it is.
Using String refs, you’ll see an input tag like this:
<input type="text" ref="textInput" />Copy the code
Then, we can get this on a value: this. Refs. (. Value – but, again, this should not be used in the new code, because the API will be abandoned.
Forwarding Refs
Ref Forwarding is a technique for passing a Ref through a component to its children. It is useful for situations such as reusable component libraries and higher-order components (HOC).
The sample address
You can use the react. forwardRef function to forward the ref to the component. Let’s look at the following example:
// Ref.js
const TextInput = React.forwardRef((props, ref) => (
<input type="text" placeholder="Hello World" ref={ref} />
));
const inputRef = React.createRef();
class CustomTextInput extends React.Component {
handleSubmit = e => {
e.preventDefault();
console.log(inputRef.current.value);
};
render() {
return (
<div>
<form onSubmit={e => this.handleSubmit(e)}>
<TextInput ref={inputRef} />
<button>Submit</button> </form> </div> ); }}Copy the code
Ref forwarding allows a component to receive a Ref and pass it down (in other words, “forward” it) to a child component.
In the example above, we created a component called TextInput using the input tag. So how do we pass or forward the ref to the input tag?
First, we create a ref using the following code:
const inputRef = React.createRef();Copy the code
We then pass ref down by specifying a JSX property of the same name for the component
. React will then pass ref as the second argument to the forwardRef function.
Next, we pass this ref parameter to . You can now access the DOM node values in the outer component via inputref.current.
Forward refs and higher-order components
Finally, let’s look at another example of using Refs, but this time using high-level components (HOC).
The sample link
In the example application above, all values entered in the input tag are printed on the console. Now that we’ve set the ref attribute for the input tag, let’s look at how we need to pass/forward the ref in the higher-order component.
const Input = InputComponent= > {
const forwardRef = (props, ref) = > {
const onType = (a)= > console.log(ref.current.value);
return <InputComponent forwardedRef={ref} onChange={onType} {. props} / >;
};
return React.forwardRef(forwardRef);
};Copy the code
There is a higher-order component called Input that takes InputComponent as an argument. As the user types, he also prints the ref value on the console.
Within the Input high-order component, the forwardRef function returns the InputComponent. The forwardRef function creates the refdref parameter. Higher-order components eventually return the wrapped component as a value.
Next, we create a component that includes the Input as a child component.
const TextInput = ({ forwardedRef, children, ... rest }) = > (
<div>
<input ref={forwardedRef} {. rest} / >
{children}
</div>
);Copy the code
The above component assigns the forwardedRef to the ref property, which is received by the input box when rendering the child component. . Rest is a deconstruction of props (that is, we pass all the parameters in the REST array as props to the Input component). So how do we use the TextInput component? Like this:
const InputField = Input(TextInput);
class CustomTextInput extends Component {
render() {
const inputRef = React.createRef();
return <InputFieldref={inputRef} />; }}Copy the code
Finally, passing TextInput into the Input higher-order component returns an InputField Component.
Create a REF and pass it as a parameter to the InputField component.
conclusion
Refs is a good way to pass data to a particular subinstance, as opposed to props and State.
You have to be careful, because Refs manipulate the actual DOM, not the virtual DOM, which contradicts the React way of thinking. So, while refs should not be the default way to flow data through your application, they are a good way to read data from DOM elements when you need them.
Recommend next “Stuart zhengmei” big guy
React v16.3.0: New lifecycles and context APIExamples from the createRef API and the forwardRef API can be read as supplements.
This article has contacted the author of the original, and authorized the translation, please keep the original link for reprinting