Понимание: Предупреждение: функциональным компонентам нельзя давать ссылки
Я знаю, что ссылки используются для прямого доступа к элементам 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>
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>
)
}
Не путайте, во-первых, это не связано с проблемой функциональных или классовых компонентов, значит, вы можете использовать ref для обоих, response 16+ имеет крючок useRef
так что вы также можете использовать ref для функциональных компонентов,
Ответь на твой вопрос, antd
Button
имеет свой собственный ref, поэтому он опускает ref, переданный родительским компонентом, в вашем случаеTooltip
вот почему вы не видите никаких предупреждений об этом, но когда вы использовали свой собственный компонент, в этот раз вы должны ref
прошло Tooltip
.
И все же вы не хотите использовать React.forwordRef
затем просто игнорируйте его, передавая реквизиты вашему компоненту. но тогда вы не получаете привилегий какой-либо функции, предоставляемойantd
контролируемые компоненты