Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 打字脚本+;反应:执行正确的参考道具_Reactjs_Typescript_Ref - Fatal编程技术网

Reactjs 打字脚本+;反应:执行正确的参考道具

Reactjs 打字脚本+;反应:执行正确的参考道具,reactjs,typescript,ref,Reactjs,Typescript,Ref,我刚刚被一个运行时异常咬伤,因为我将一个React ref传递到了错误的组件中 我想知道TypeScript是否/如何能在这里保存我的培根 简化测试用例: import * as React from 'react'; class Modal extends React.Component<{}> { close = () => {}; } declare const modal: Modal; modal.close(); const modalRef = R

我刚刚被一个运行时异常咬伤,因为我将一个React ref传递到了错误的组件中

我想知道TypeScript是否/如何能在这里保存我的培根

简化测试用例:

import * as React from 'react';

class Modal extends React.Component<{}> {
    close = () => {};
}

declare const modal: Modal;

modal.close();

const modalRef = React.createRef<Modal>();

// Let's try giving this ref to the correct component…
// No error as expected :-)
<Modal ref={modalRef} />;

class SomeOtherComponent extends React.Component<{}> {}

// Let's try giving this ref to the wrong component…
// Expected type error but got none! :-(
<SomeOtherComponent ref={modalRef} />;

// Now when we try to use this ref, TypeScript tells us it's safe to do so.
// But it's not, because the ref has been incorrectly assigned to another component!
if (modalRef.current !== null) {
    modalRef.current.close() // runtime error!
}
import*as React from'React';
类Modal扩展了React.Component{
close=()=>{};
}
声明常量模态:模态;
modal.close();
const modalRef=React.createRef();
//让我们尝试将此引用指定给正确的组件…
//没有预期的错误:-)
;
类SomeOtherComponent扩展React.Component{}
//让我们尝试将此引用指定给错误的组件…
//应为类型错误,但未得到任何错误!:-(
;
//现在当我们尝试使用这个ref时,TypeScript告诉我们这样做是安全的。
//但事实并非如此,因为ref被错误地分配给了另一个组件!
if(modalRef.current!==null){
modalRef.current.close()//运行时错误!
}

可能的解决方案是使用类和引用的接口

接口IModal{ close():void; } 类模态扩展了React.Component实现了IModal{ close=()=>{}; } const modalRef=React.createRef(); //类型“REOBJECT”不能分配给类型“string |”((实例://SomeOtherComponent | null)=>void)| REOBJECT | null |未定义”。 //类型“REOBJECT”不可分配给类型“REOBJECT”。 //类型“IModal”缺少类型“SomeOtherComponent”中的以下属性:render、context、setState、forceUpdate和其他3个属性。TS2322
可能的解决方案是使用类和引用的接口

接口IModal{ close():void; } 类模态扩展了React.Component实现了IModal{ close=()=>{}; } const modalRef=React.createRef(); //类型“REOBJECT”不能分配给类型“string |”((实例://SomeOtherComponent | null)=>void)| REOBJECT | null |未定义”。 //类型“REOBJECT”不可分配给类型“REOBJECT”。 //类型“IModal”缺少类型“SomeOtherComponent”中的以下属性:render、context、setState、forceUpdate和其他3个属性。TS2322
ref没有出现任何错误的原因是,在您的示例中,两个组件都是相同基类React.Component的派生,但它们没有任何不同的属性,也没有显式接口

检查Typescript中有关类型兼容性的部分:

由于Typescript使用结构化子类型而不是名义子类型,因此在以下情况下,可以合并类并进行相等的比较:

  • 两者都有相同的属性成员
  • 也没有任何属性成员(这不是一个现实的情况,但它是您拥有的)
  • 一个类可以有另一个类没有的成员,但前提是它具有另一个类的所有属性。例如,它可以添加内容,但不能引入新的内容
  • 构造函数可以不同
  • 也可以重新定义同一属性成员
在所有其他情况下,它们都不兼容

如果您改写为:

React.createRef();

例如,您将清楚地看到,参照在组件上被概括为不兼容

这是因为React.Component在任何方面都与HtmleElement类型不兼容(HTMLInputElement是HtmleElement的派生类型,例如,这些类具有不同的属性)

这并不是说这个断言不起作用,而是它在引擎盖下到底是如何起作用的,它遵循上面概述的规则

回到手头的问题

根据你的情况,你可以做几件事来避免这类问题

您有两个组件,具有不同的react道具

如果您的组件具有不同的道具,请为两者创建接口,这样您就不会有此问题,因为它将返回一个类型错误,这些组件上的道具不匹配,这是真的

您有两个组件,没有自定义的react属性

您当前的问题。如果将新属性成员添加到类模式中不存在的其他组件,例如,
open=()=>
,则它们将被视为不同的解决方案

摘要

如果您不能添加接口,并且这两个类中没有不同的属性成员,那么这是同一个类就足够现实了


您只需要找出一种更好的方法,如何在这两种情况下使用它。

ref没有出现任何错误的原因在于,您的两个组件都是同一基类的派生。在您的示例中,React.Component,但它们没有任何不同的属性,也没有显式的接口

检查Typescript中有关类型兼容性的部分:

由于Typescript使用结构化子类型而不是名义子类型,因此在以下情况下,可以合并类并进行相等的比较:

  • 两者都有相同的属性成员
  • 也没有任何属性成员(这不是一个现实的情况,但它是您拥有的)
  • 一个类可以有另一个类没有的成员,但前提是它具有另一个类的所有属性。例如,它可以添加内容,但不能引入新的内容
  • 构造函数可以不同
  • 也可以重新定义同一属性成员
在所有其他情况下,它们都不兼容

如果您改写为:

React.createRef();

例如,您将清楚地看到,参照在组件上被概括为不兼容

这是因为React.Component在任何方面都与HtmleElement类型不兼容(HTMLInputElement是HtmleElement的派生类型,例如,这些类具有不同的属性)

这并不是说这个断言不起作用,而是它在引擎盖下到底是如何起作用的,它遵循上面概述的规则

回到手头的问题

你可以