SpinButton:public 属性 'value' 未定义且 public 方法 'focus()' 不是函数

SpinButton: public property 'value' is undefined and public method 'focus()' is not a function

我最近开始使用 reactjs、typescript 和 Office UI Fabric。但我已经在为 fabric 的其中一个组件而苦苦挣扎。 在此示例中,我有一个简单的 Product 组件,其中包含一个 SpinButton 和一个 DefaultButton。 单击 DefaultButton 时,我想获取 SpinButton 的值并将焦点设置在它上面。 为了获得 ISpinButton 接口成员,我使用了 React.RefObject 的引用。 我的代码如下所示:

import * as React from 'react';

import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import { SpinButton } from 'office-ui-fabric-react/lib/SpinButton';

class Product extends React.Component<{}, {}> {

    private spbStockRef: React.RefObject<SpinButton> = React.createRef<SpinButton>();

    public render(): JSX.Element {
        return (
            <React.Fragment>
                <SpinButton
                    ref={this.spbStockRef}
                    defaultValue="0"
                    label={'Stock '}
                    min={0}
                    max={99999}
                    step={1}
                    onFocus={() => console.log('onFocus called')}
                    onBlur={() => console.log('onBlur called')} />
                <DefaultButton onClick={this.onButtonClick} />
            </React.Fragment>)
    }

    private onButtonClick = (e: React.MouseEvent<HTMLButtonElement>) => {
        const node = this.spbStockRef.current!;

        if (node) {
            console.log(node.value);
            node.focus();
        }
    }
}
export default Product;

在 onButtonClick 内部,Visual Studio 的智能感知建议在节点变量上同时使用 'value' 和 'focus()',因此应该可以访问实际的 ISpinButton 成员。

但是当单击按钮时,console.log(node.value) 输出 undefined 并且在 node.focus() 上引发 TypeError: 类型错误:node.focus 不是函数。 我还想提一下 console.log(node) 输出一个正确的实例化对象,因此 ref 工作正常。

知道我做错了什么吗? 在 SpinButton 组件的示例中,也没有指出如何使其工作。

https://developer.microsoft.com/en-us/fabric?example=#/components/spinbutton

谢谢

对于 fabric-ui,要将 ref 附加到内部元素而不是组件,您可以使用 componentRef

这将为 SpinButton:

创建代码
<SpinButton
   componentRef={this.spbStockRef}
   defaultValue="0"
   label={'Stock '}
   min={0}
   max={99999}
   step={1}
/>

const { SpinButton } = window.Fabric;

class App extends React.Component {
  spinBtn = React.createRef();
  componentDidMount() {
    this.spinBtn.current.focus();
  }
  render() {
    return (
      <SpinButton
        defaultValue="0"
        label={'Basic SpinButton:'}
        min={0}
        max={100}
        step={1}
        componentRef={this.spinBtn}
        iconProps={{ iconName: 'IncreaseIndentLegacy' }}
      />
    );
  }
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);
<link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.1/css/fabric.min.css">
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="//unpkg.com/office-ui-fabric-react/dist/office-ui-fabric-react.min.js"></script>
<div id="root"></div>

灵感来自 Boy With Silver Wings 他的回答,我找到了解决方法。我没有为 RefObject 使用特定类型,而是将其声明为 any 然后我就可以使用 componentRef 了。 所以基本上我必须覆盖 componentRef 所需的类型 (component?: ISpinButton | null) => void 才能使其工作。我不知道这是否应该作为错误报告。

import * as React from 'react';

import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import { SpinButton } from 'office-ui-fabric-react/lib/SpinButton';

class Product extends React.Component<{}, {}> {

    private spbStockRef: any = React.createRef();

    public render(): JSX.Element {
        return (
            <React.Fragment>
                <SpinButton
                    componentRef={this.spbStockRef}
                    defaultValue="0"
                    label={'Stock '}
                    min={0}
                    max={99999}
                    step={1}
                    onFocus={() => console.log('onFocus called')}
                    onBlur={() => console.log('onBlur called')} />
                <DefaultButton onClick={this.onButtonClick} />
            </React.Fragment>)
    }

    private onButtonClick = (e: React.MouseEvent<HTMLButtonElement>) => {
        const node = this.spbStockRef.current!;

        if (node) {
            console.log(node.value);
            node.focus();
        }
    }
}
export default Product;