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

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

Ссылки не могут быть прикреплены к функциональным компонентам. Хотя мы можем определить ссылки и прикрепить их либо к элементам DOM, либо к компонентам класса. Суть в том, что у функциональных компонентов нет экземпляров, поэтому вы не можете ссылаться на них.

взято из: https://blog.logrocket.com/cleaning-up-the-dom-with-forwardref-in-react/

Я все еще не понимаю.

Я использую компонент Tooltip от Ant Design (https://ant.design/components/tooltip/ ), компонент Button и пользовательский компонент CircleButton.

Учитывая следующий JSX:

<Tooltip placement="left" title={"Lock slot"}>
  <CircleButton onClick={() => execute(client.close)} icon={<LockOutlined />} disabled={loading} />
</Tooltip>

И мой компонент CircleButton. При таком использовании генерируется предупреждение.

const CircleButton = (props) => // gives the warning
  <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />

Предупреждение: функциональным компонентам нельзя давать ссылки. Попытки получить доступ к этой ссылке потерпят неудачу. Вы хотели использовать React.forwardRef ()?

Обратите внимание, что все работает, как ожидалось, несмотря на предупреждение.

Если я отредактирую его следующим образом, он будет работать нормально, почему?

const CircleButton = forwardRef((props, ref) => // doesn't give the warning
  <div ref={ref}>
    <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />
  </div>)

Есть ли состояние у компонента div? Я не понимаю. forwardRef творит чудеса и создает состояние для элемента div?

Почему тогда, если я передаю ref компоненту Button, он все равно выдает предупреждение?

const CircleButton = forwardRef((props, ref) => // gives the warning
  <Button ref={ref} shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />)

Если я передам antd Button прямо в детстве, он сработает. Но это потому, что я полагаю, что кнопка antd имеет состояние, следовательно, у нее могут быть ссылки.

<Tooltip placement="left" title={"Lock slot"}> // doesn't give the warning
  <Button shape="circle" size="small" style={{ marginRight: "8px" }} />
</Tooltip>

person devamat    schedule 27.04.2020    source источник


Ответы (2)


В качестве состояния предупреждения вы не можете назначить ссылки функциональному компоненту без использования forwardRef

Чтобы иметь доступ к ссылкам любого компонента, требуется, чтобы был создан экземпляр компонента, а экземпляр создавался только для компонентов класса, в то время как функциональные компоненты вызываются или вызываются

Начиная с версии v16.8.0, React представил API под названием useRef, который позволяет вам создавать ссылки в функциональных компонентах, которые можно использовать на узлах HTML, компонентах классов или функциональных компонентах, заключенных в forwardRef.

Чтобы добиться того же поведения, которое доступно в компонентах класса с ref, вы можете использовать forwardRef с ловушкой useImperativeHandle, чтобы предоставить определенные функции или состояния в функциональном компоненте для родительского

const CircleButton = forwardRef((props, ref) => {
  const someFunction = () =>{}
  useImperativeHandle(ref, () => ({
     someFunc
  }));

  return (
    <div>
        <Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />
   </div>

  )
}
person Shubham Khatri    schedule 27.04.2020

Не путайте, во-первых, это не связано с проблемой функциональных или классовых компонентов, это означает, что вы можете использовать ref для обоих, response 16+ имеет крючок useRef, поэтому вы также можете использовать ref для функциональных компонентов,

Ответьте на ваш вопрос: у antd Button есть свои ref, поэтому он опускает ref, переданный родительским компонентом в вашем случае Tooltip, почему вы не видите никаких предупреждений об этом, но когда вы использовали свой собственный компонент, в этот раз вам нужно взять ref, переданный Tooltip.

И, тем не менее, вы не хотите использовать React.forwordRef, а затем просто игнорируйте его при передаче свойств вашему компоненту. но тогда вы не получаете привилегий на некоторые функции, предоставляемые antd контролируемыми компонентами

person chandawarlokesh    schedule 27.04.2020