【问题标题】:How to annotate a react functional component with both props and states?如何使用道具和状态注释反应功能组件?
【发布时间】:2021-03-30 08:56:11
【问题描述】:

我正在构建一个反应原生应用程序。我有一个父组件和一个子组件。子组件有一个按钮,其事件处理程序位于父组件中。在事件处理程序结束时,我还必须更新子组件中的特定状态。所以出于这个原因,我在父组件中使用了useRef 钩子来创建子组件的引用。现在,事件处理函数看起来像这样

const handleJoin = async (community: TCommunity) => {
    // ..........
    childComponentRef.current.setIsDataManipulated(true);
    // ..........
};

但我在setIsDataManipulated 中得到一条红色波浪线,当我将鼠标悬停在它上面时,会出现以下错误

Property 'setIsDataManipulated' does not exist on type 'FC<TChildrenProps>'

这一定是因为打字稿无法知道子组件具有我要更新的状态。目前,我只使用 props 类型而不是 state 类型来注释子组件。我在网上搜索过,发现在使用基于类的组件时,我可以传递第二个泛型类型如React.Component&lt;TProps, TState&gt; 来对props 和state 进行注释。但是我如何使用React.FC 这样做呢?

【问题讨论】:

  • 我不确定childComponentRef.current.setIsDataManipulated(true); 是不是个好主意。我同意@T.J。克劳德,你最好把它当作道具:don't make it state in the child component, make it a prop

标签: reactjs typescript react-native


【解决方案1】:

这一定是因为 typescript 无法知道子组件具有我正在尝试更新的状态。

不,这是因为元素没有使用该名称的公开方法/函数,原因如下:

  • ref 将引用一个 DOM 元素。
  • 但即使它指的是子组件实例,虽然该实例在其实现中可能有一个 setIsDataManipulated 函数,但它不会以任何方式暴露给父组件。

这不是 TypeScript 的事情(尽管 TypeScript 很早就指出了这一点),childComponentRef.current 上根本不存在该方法/函数。

如果你想让父组件控制子组件中的状态,不要让它在子组件中成为状态,让它成为一个道具。这就是 props 的含义:由它们提供给子组件的父组件控制的状态。如果子组件也必须告诉父组件prop需要更改,让父组件传递一个setter来使用。

我在网上搜索过,发现在使用基于类的组件时,我可以传递第二个泛型类型,如React.Component&lt;TProps, TState&gt; 来注释道具和状态。但是我如何使用React.FC 这样做呢?

不,React.FC (React.FunctionComponent) 只有一个类型参数,用于道具。它没有理由为 state 提供类型参数,因为它不会用于任何事情。使用React.Component,状态类型参数确定组件代码实例的state 属性是什么,以便可以对class 组件内使用this.state 和this.setState 的代码进行类型检查。但是函数组件中的状态不是这样工作的。没有单一的状态对象。相反,当使用useState 时,您可以直接定义每个状态成员的类型。

这是一个示例:一个 class 组件具有一个 prop 和两个状态项,而一个函数组件具有相同的 prop 和状态项:

class ClassExample extends React.Component<{prop1: string}, {state1: number; state2: string | null}> {
    constructor(props: {prop1: string}) {
        super(props);
        this.state = {
            state1: 42,     // If these weren't here, TypeScript
            state2: null,   // would warn they were missing, thanks
                            // to the state type argument
        };
    }
    // ...
}

const FunctionExample: React.FC<{prop1: string}> = ({prop1}) => {
    const [state1, setB] = useState(42); // TypeScript infers `number` for type
    const [state2, setC] = useState<string | null>(null); // Explicit so TypeScript knows it's `string | null`

    // ...
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-11
    • 2021-06-10
    • 2021-05-31
    • 2021-01-24
    • 1970-01-01
    • 2021-06-11
    • 2020-12-26
    • 2022-11-21
    相关资源
    最近更新 更多