I Refs & DOM
1.1 usage scenarios
- Manage focus, text selection, or media playback.
- Trigger forced animation.
- Integrate third-party DOM libraries.
1.2 creating refs
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } }
You can directly use this.props???
The value of ref varies according to the type of node:
- When the ref attribute is used for HTML elements, the ref created using React.createRef() in the constructor receives the underlying DOM element as its current attribute.
- When the ref attribute is used to customize a class component, the ref object receives the mounted instance of the component as its current attribute.
Does the function component have a ref
For the original react, you cannot use the ref attribute on function components because they have no instances.
However, in hook, if you want to use ref in a function component, you can use forwardRef (which can be used in combination with useImperativeHandle), or you can convert the component into a class component.
In any case, you can use the ref attribute inside the function component as long as it points to a DOM element or class component:
function CustomTextInput(props) { // textInput must be declared here so that ref can reference it const textInput = useRef(null); function handleClick() { textInput.current.focus(); } return ( <div> <input type="text" ref={textInput} /> <input type="button" value="Focus the text input" onClick={handleClick} /> </div> ); }
1.3 exposing DOM Refs to parent components
In rare cases, you may want to reference the DOM node of the child node in the parent component.
This is generally not recommended because it breaks the encapsulation of components, but it can occasionally be used to trigger focus or measure the size or position of child DOM nodes.
- Implementation 1: add ref s to sub components, but this is not an ideal solution because you can only get component instances instead of DOM nodes. Also, it is not valid on function components
- Implementation 2: ref forwarding
- Implementation method 3: When the child component is initialized, the ref is passed to the parent component through events
II Refs forwarding
ref forwarding is a technique for automatically passing refs through a component to one of its subcomponents. This is usually not required for components in most applications. However, it may be inconvenient for highly reusable "leaf" components such as FancyButton or MyTextInput. These components tend to be used in the whole application in a way similar to conventional DOM button s and inputs, and accessing their DOM nodes is inevitable for managing focus, selection or animation.
Ref forwarding is an optional feature that allows some components to receive a ref and pass it down (in other words, "forward" it) to child components.
const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children} </button> )); // You can directly get the ref of DOM button: const ref = React.createRef(); <FancyButton ref={ref}>Click me!</FancyButton>;
be careful
The second parameter ref exists only when the component is defined using React.forwardRef. Regular functions and class components do not receive ref parameters, and ref does not exist in props.
Ref forwarding is not limited to DOM components. You can also forward refs to class component instances.
III Callback Refs
React also supports another way to set refs, called "callback refs". It can help you more finely control when refs is set and released.
Instead of passing the ref attribute created by createRef(), you pass a function. This function accepts React component instances or HTML DOM elements as parameters so that they can be stored and accessed elsewhere.
class CustomTextInput extends React.Component { constructor(props) { super(props); this.textInput = null; this.setTextInputRef = element => { this.textInput = element; }; this.focusTextInput = () => { // Use the native DOM API to focus the text input box if (this.textInput) this.textInput.focus(); }; } componentDidMount() { // After the component is mounted, let the text box automatically get the focus this.focusTextInput(); } render() { // Use the callback function of 'ref' to store the reference of the DOM node of the text input box in React // Instance (such as this.textInput) return ( <div> <input type="text" ref={this.setTextInputRef} /> <input type="button" value="Focus the text input" onClick={this.focusTextInput} /> </div> ); } }
React will call the ref callback function and pass in the DOM element when the component is mounted, and call it and pass in null when the component is unloaded. Before componentDidMount or componentDidUpdate is triggered, react will ensure that refs must be up-to-date.