createRef и useRef - это два разных инструмента в React для работы с рефами (refs), которые позволяют получать доступ к DOM элементам и другим компонентам.

createRef()

createRef - это метод React, который позволяет создавать рефы (refs) для доступа к DOM элементам и другим компонентам в методах жизненного цикла компонента. Она возвращает { current: null } .

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }
 
  render() {
    return <div ref={this.myRef}>Hello, World!</div>
  }
}

В этом примере, createRef() используется для создания рефа myRef. Реф передается в DOM элемент через атрибут ref.

Также в атрибут ref можно передавать не только объект вида  { current: T }, но и функцию, которая единственным аргументом принимает ссылку на элемент, этот прием называется ref callback:

class ClassComponent extends Component {
  element = null
 
  componentDidMount() {
    // после рендеринга в this.element попадет ссылка на элемент
    console.log(this.element.offsetWidth)
  }
 
  render() {
    return <div ref={(elem) => (this.element = elem)}>Элемент с текстом</div>
  }
}

Главная задача ref callback - это создание массива ссылок на DOM элементы и react компоненты.

useRef()

useRef - это хук, который позволяет создавать рефы (refs) для доступа к DOM элементам и другим компонентам в функциональных компонентах.

const ref = useRef(initialValue)

При попытке получить ссылку на функциональный компонент мы получим другой результат нежели при использовании createRef(). А в консоли увидим следующее предупреждение и получим undefined вместо данных компонента.

Функциональные компоненты нужно обернуть в forwardRef, так внутри функционального компонента мы получим второй аргумент ref и сможем его передать в нужный html элемент. Либо этот ref нужно передать в useImperativeHandle - это специальный хук, который добавит в ref дополнительные свойства. Это позволит поднимать из функционального компонента данные и методы.

Синтаксис useRef() представлен ниже:

function MyComponent() {
  const myRef = useRef(null)
  return <div ref={myRef}>Hello, World!</div>
}

В этом примере, useRef() используется для создания рефа myRef. Реф передается в DOM элемент через атрибут ref.

useRef() в функциональных компонентах используются не только для доступа к DOM элементам, но еще и как стабильное хранилище данных.

Как переслать несколько ссылок?

Чтобы переслать несколько ссылок с помощью React, мы можем передать ссылки в объекте.

Например, мы пишем:

import React, { useRef } from "react"
 
const Child = React.forwardRef((props, ref) => {
  const { ref1, ref2 } = ref.current
  console.log(ref1, ref2)
 
  return (
    <>
      <p ref={ref1}>foo</p>
      <p ref={ref2}>bar</p>
    </>
  )
})
 
export default function App() {
  const ref1 = useRef()
  const ref2 = useRef()
  const ref = useRef({ ref1, ref2 })
 
  return <Child ref={ref} />
}

У нас есть Child компонент, который принимает ссылки с тех пор, как мы создали его, вызвав forwardRef с помощью функции компонента.

В функции мы деструктурируем ссылки, которые мы передаем, используя:

const { ref1, ref2 } = ref.current

Затем мы присваиваем ref1 и ref2 элементам p.
В приложении мы создаем ссылки с помощью useRef-хука.
Мы создаем ref, вызывая useRef с объектом, созданным из существующих ссылок.

И, наконец, мы устанавливаем ref prop Child элемента на ref.

Следовательно, из console.log() мы можем видеть, что текущее свойство ref1 и ref2 присвоено элементам абзаца в дочернем элементе.


Назад