Понимание: Предупреждение: Функциональные компоненты не могут быть даны ссылки - PullRequest
0 голосов
/ 27 апреля 2020

Я знаю, что ссылки используются для прямого доступа к элементам 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 выполняет магию c и создает состояние для элемента 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>

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

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

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

Начиная с версии 16.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>

  )
}
0 голосов
/ 27 апреля 2020

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

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

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

...