🔏
PexpA
  • Home
  • Knowledge
    • Design Pattern
    • RxJS
    • Computer Graphics
      • Phép biến đổi hình học
    • Javascript
      • Generator function và Yield trong javascript
      • Asynchronous và Synchronous
    • GraphQL
      • Core Concepts
      • Xây dựng GraphQL sử dụng NodeJS
    • Analysis and System Design
    • SEO
    • Database
      • NoSQL
        • MongoDB
      • SQL
    • ReactJS
      • React Fragment
      • Lifecycle trong component
      • HOCs
      • What is Ref ?
      • Context API
      • React Hooks
        • useState Hook
        • useEffect Hook
        • useLayoutEffect Hook
        • Khi nào dùng useLayoutEffect và useEffect
        • useContext Hook
        • useReducer Hook
        • useCallback Hook
        • useMemo Hook
        • useRef Hook
        • Building Your Own Hooks
      • Redux
    • React Native
      • Animations
    • Angular
    • Python
      • Object Oriented Programming
      • Decorator
      • Multi Threading
      • Generators
      • Iterators
    • Java
    • Blockchain
      • Ethereum Development Overview
      • Solidity Document
      • JSON RPC Protocol
  • Package
    • React Router V4
    • API Documentation
      • API Blueprint
      • Swagger
    • Lazyload image
    • React Helmet
    • React Spring
    • React Apollo
    • ImmerJS
    • Styled components
  • Experience
    • Sử dụng Latex trên VSCode
    • Linked List in C++
    • How to using Date, Time, TimeStamp for Java to connect Database
    • Pass props to a component rendered by React Router v4
    • Forking Workflow
  • Deploy
    • Heroku
      • How to deploy React App with Express
      • How to deploy React App with Python
      • How to deploy React App with Java
  • About me
Powered by GitBook
On this page
  • Forwarding Refs
  • Một số trường hợp dùng refs
  • Các ví dụ

Was this helpful?

  1. Knowledge
  2. ReactJS

What is Ref ?

PreviousHOCsNextContext API

Last updated 4 years ago

Was this helpful?

React refs là một tính năng hữu ích, nó là cách mà chúng ta có thể để tham chiếu một element trong DOM hoặc từ một class component con đến component cha. Điều này cho phép chúng ta đọc và chỉnh sửa các element đó.

Cách giải thích dễ hiểu nhất về React Refs là tưởng tượng nó là một cây cầu. Khi một element được gán vào một ref nó sẽ cho phép chúng ta sửa đổi cũng như truy cập vào element đó ngay lập tức và không cần sử dụng đến props hay state để component re-render. Nó giống cho phép việc can thiệp vào DOM như trong Javascript DOM

document.getElementsByTagName('h1').innerHTML = 'Freetuts.net'

Chúng ta có thể can thiệp trực tiếp vào DOM qua refs mà không cần thông qua việc render. Mặc dù đây là cách để can thiệp vào DOM thuận tiện mà không cần phải sử dụng đến state, props nhưng điều này React không khuyến khích. Bởi khi các DOM bị thay đổi thì nó sẽ ảnh hưởng một phần nào đó đến quá trình render các component. Các bạn nên sử dụng React refs để can thiệp vào DOM trong trường hợp cần thiết.

Forwarding Refs

Forwarding Refs là một kỹ thuật để tự động chuyển một ref từ một component tới component con, cho phép component cha có thể tham chiếu tới các element của component con để đọc và chỉnh sửa nó.

React cung cấp cho chúng ta một cách thức để thực hiện việc chuyển tiếp một ref, chúng ta sẽ bao component con trong React.forwardRef(), ở đây mình có ví dụ:

//Component Con
const MyInput = React.forwardRef((props, ref) => {
   return(<input name={props.name} ref={ref} />);
});
// Component Cha
const MyComponent = () => {
   let ref = React.createRef();
   return (
     <MyInput
       name="email"
       ref={ref}
     />
   );
}

Ví dụ bên trên mình đã sử dụng React.forwardRef(), ở đây nó cung cấp cho chúng ta 2 tham số lần lượt là props và refs, cho chúng ta nhận về giá trị của props và refs từ component cha.

Một số trường hợp dùng refs

  • Control focus, get text của DOM element, get state value(play/pause/timeline) của media playback,... nói chung là dùng trong những trường hợp các data này không cần đưa vào state của component.

  • Trigger các transitions, animations: sử dụng refs khi một element cần trigger animation/transition của một element khác

  • Tích hợp với các Third-party DOM libraries

Các ví dụ

Điều khiển focus của input:

Ở ví dụ này, chúng ta sẽ sử dụng userRef để tham chiếu tới input element, sau đó sẽ thực hiện focus input khi click button

import React, { useRef } from "react";

function App() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div className="App">
      <h2>Use refs to control focus</h2>
      <input ref={inputEl} />
      <button onClick={onButtonClick}>Focus the input</button>
    </div>
  );
}

Set/Get giá trị trước đó của state:

Ở ví dụ này; sẽ có 1 input, nhập một vài ký tự và thực hiện blur input đó, chúng ta sẽ check xem previous value, current value sau mỗi lần blur input (case này trong thực tế là: nếu sau mỗi lần blur mà giá trị trước và sau khi blur có thay đổi thì thực hiện call api, ngược lại nếu không thay đổi thì không làm gì cả)

import React, { useRef, useState } from "react";

function App() {
  const prevValue = useRef("");
  const [value, setValue] = useState("");

  const onInputChange = e => {
    setValue(e.target.value);
  };

  const onInputBlur = () => {
    console.log(`Previous value: ${prevValue.current}`);
    console.log(`Current value: ${value}`);
    prevValue.current = value;
  };

  return (
    <div className="App">
      <h2>Use refs to set/get previous state's value</h2>
      <input value={value} onBlur={onInputBlur} onChange={onInputChange} />
      <div>Type something, blur input and check result in console.log</div>
    </div>
  );
}

Sau khi hiểu về useRef ở ví dụ trên, chúng ta sẽ hay gặp 1 trường hợp thực tế như sau: sau khi input data vào các field trên màn hình(route A) sau đó điều hướng sang route B, lúc này ta sẽ cần lưu các data trên màn hình vào redux store như sau:

import React, { useState, useEffect, useRef } from "react";

function App() {
  const onScreenData = useRef({});
  const [inputs, setInputs] = useState({});

  const onInputChange = e => {
    const [name, value] = e.target;
    const updatedInputs = { ...inputs, [name]: value };
    setInputs(updatedInputs);
    onScreenData.current = updatedInputs;
  };

  useEffect(
    () => () => {
      saveScreenData(onScreenData.current);
    },
    []
  );

  return (
    <div>
      <h2>Use refs to get the latest inputs value</h2>
      <label>Title: </label>
      <input name="title" value={inputs.title || ""} onChange={onInputChange} />
      <label>Note: </label>
      <input name="note" value={inputs.note || ""} onChange={onInputChange} />
    </div>
  );
}

const saveScreenData = data => {
  // Save data to redux store
};

Control animation:

Chúng ta sử dụng useRef để get tham chiếu đến DOM element và thực hiện trigger animation

import React, { useRef, useEffect } from "react";
import { TweenMax } from "gsap";

function App() {
  const circle = useRef(null);

  useEffect(() => {
    TweenMax.fromTo(
      [circle.current],
      0.5,
      { y: 18 },
      { y: -18, yoyo: true, repeat: -1 }
    );
  }, []);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <svg viewBox="0 0 150 33.2" width="180" height="150">
        <circle ref={circle} cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
      </svg>
    </div>
  );
}

Demo:

Demo:

Demo:

Demo:

https://codesandbox.io/s/dawn-thunder-w9hur
https://codesandbox.io/s/hungry-glade-d7mjb
https://codesandbox.io/s/distracted-banzai-3hrwb
https://codesandbox.io/s/sleepy-mendel-lc8kz
Đây chỉ là hình minh họa