【问题标题】:React ref for a function component, unable to acquire a reference: "Function components cannot be given refs"React ref for a function component,无法获取引用:“Function components cannot be given refs”
【发布时间】:2021-08-24 05:24:15
【问题描述】:

我正在使用 fluentui/react-nothstar 包控件构建一个 React 网站。您可以在下面找到文本 + 按钮的简化示例。我的方案是在按下按钮时访问文本控件。我需要类似 document.findElementById 的东西,它通过refs in React 工作。它适用于组件控件(扩展 React.Component),但对于 Northstar 组件失败并出现错误:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

根据警告细节和文本控件定义,它看起来像是一个函数组件,我必须使用React forwardRef 来访问它的属性。我尝试了多种方法来做到这一点hereherehere,但都没有成功。

import React from 'react';
import {
    Text,
    Button,
}
    from '@fluentui/react-northstar';

class Welcome extends React.Component {

    private textRef: any = React.createRef();

    private doJob1() {
        console.log("doJob1 executed");
        console.log(this.textRef.current); // returns null
    }

    render() {
        return (
            <div>
                <div>Welcome</div>
                <div>
                    <Text
                        ref={this.textRef}
                        content="My fancy text control" />
                    <Button
                        onClick={this.doJob1.bind(this)}
                        content="My fancy button" />

                </div>
            </div>
        );
    }
}

export default Welcome;

在大多数情况下,我可以通过使用 props 和 state 来避免直接访问元素,但在某些情况下,我仍然需要一个组件引用(更改焦点、打开对话框、更新未在我的 state 中定义的值)。

在上例中,在 Button 点击​​处理程序中访问 Text 控件的正确方法是什么?

【问题讨论】:

    标签: javascript reactjs typescript ref react-forwardref


    【解决方案1】:

    在这种情况下,库需要转发引用,which apparently they don't

    但一般来说,您希望使用controlled components 来捕获这样的用户输入。基本上,您需要设置一个变量来跟踪父组件中的值(欢迎,在您的情况下),将其作为value 传递给&lt;Text /&gt; 组件并从其onChange 捕获更改。然后,在按钮的onClick 上,无论用户输入什么,该值都将是最新的。

    【讨论】:

    • 谢谢!这正是我用来维护单一事实来源的方法,它在大多数情况下都能正常工作,但并非全部。例如,Datepicker onDateChange 不提供 event.target.value 中的新值,我需要控件引用来读取值:github.com/microsoft/fluentui/issues/18458
    • 我不知道 fluent ui 的细节,但是你试过 onDateChange={console.log},看看它返回的格式是什么?
    • 如果我打印 tp 控制台 event.target,而不是控件,它会给我 datePicker 按钮 &lt;button role="gridcell" data-aa-class-'DatepickerCalendarCellButton; ... /&gt;,我无法通过通常的 event.target.value 获取值。
    【解决方案2】:

    原来Ref 就是为此而设计的:

    <Ref innerRef={this.textRef}>
        <Text content="My fancy text control" />
    </Ref>
    

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 2019-10-26
      • 2020-11-24
      • 2019-04-03
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多