Javascript Typescript:反应事件类型

Javascript Typescript:反应事件类型,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,React事件的正确类型是什么。最初,为了简单起见,我只使用了any。现在,我正在努力清理,完全避免使用any 以这样一种简单的形式: export interface LoginProps { login: { [k: string]: string | Function uname: string passw: string logIn: Function } } @inject('login') @observer export class Logi

React事件的正确类型是什么。最初,为了简单起见,我只使用了
any
。现在,我正在努力清理,完全避免使用
any

以这样一种简单的形式:

export interface LoginProps {
  login: {
    [k: string]: string | Function
    uname: string
    passw: string
    logIn: Function
  }
}
@inject('login') @observer
export class Login extends Component<LoginProps, {}> {
  update = (e: React.SyntheticEvent<EventTarget>): void => {
    this.props.login[e.target.name] = e.target.value
  }
  submit = (e: any): void => {
    this.props.login.logIn()
    e.preventDefault()
  }
  render() {
    const { uname, passw } = this.props.login
    return (
      <div id='login' >
        <form>
          <input
            placeholder='Username'
            type="text"
            name='uname'
            value={uname}
            onChange={this.update}
          />
          <input
            placeholder='Password'
            type="password"
            name='passw'
            value={passw}
            onChange={this.update}
          />
          <button type="submit" onClick={this.submit} >
            Submit
          </button>
        </form>
      </div>
    )
  }
}
导出接口登录操作{
登录:{
[k:string]:字符串|函数
uname:string
passw:string
登录:函数
}
}
@注入('login')@observer
导出类登录扩展组件{
更新=(e:React.SyntheticEvent):void=>{
this.props.login[e.target.name]=e.target.value
}
提交=(e:任何):无效=>{
this.props.login.login()
e、 预防默认值()
}
render(){
const{uname,passw}=this.props.login
返回(
提交
)
}
}
我在这里使用什么类型作为事件类型

React.SyntheticEvent
似乎不起作用,因为我收到一个错误,
name
value
target
上不存在

对于所有事件的更普遍的答案,我们将不胜感激


谢谢

问题不在于事件类型,而在于typescript中的EventTarget接口只有3种方法:

interface EventTarget {
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
    dispatchEvent(evt: Event): boolean;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

interface SyntheticEvent {
    bubbles: boolean;
    cancelable: boolean;
    currentTarget: EventTarget;
    defaultPrevented: boolean;
    eventPhase: number;
    isTrusted: boolean;
    nativeEvent: Event;
    preventDefault(): void;
    stopPropagation(): void;
    target: EventTarget;
    timeStamp: Date;
    type: string;
}
因此,
name
value
在EventTarget上不存在是正确的。您需要做的是将目标强制转换为具有所需属性的特定元素类型。在这种情况下,它将是
HTMLInputElement

update = (e: React.SyntheticEvent): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}
此外,对于事件而不是React.SyntheticEvent,您还可以按以下方式键入它们:
事件
鼠标事件
键盘事件
…等等,具体取决于处理程序的使用情况

查看所有这些类型定义的最佳方法是从typescript和react中签出.d.ts文件

另请查看以下链接以了解更多说明: 该界面是通用的:

interface SyntheticEvent<T> {
    ...
    currentTarget: EventTarget & T;
    ...
}

(注意:此答案最初建议使用
React.FormEvent
。评论中的讨论与此建议相关,但
React.changevent
应如上所示使用。)

要结合Nitzan和Edwin的答案,我发现类似的方法对我有效:

update = (e: React.FormEvent<EventTarget>): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}
update=(e:React.FormEvent):void=>{
让target=e.target作为HTMLInputElement;

this.props.login[target.name]=target.value; }
我认为最简单的方法是:

type InputEvent = React.ChangeEvent<HTMLInputElement>;
type ButtonEvent = React.MouseEvent<HTMLButtonElement>;

update = (e: InputEvent): void => this.props.login[e.target.name] = e.target.value;
submit = (e:  ButtonEvent): void => {
    this.props.login.logIn();
    e.preventDefault();
}
type InputEvent=React.ChangeEvent;
类型ButtonEvent=React.MouseEvent;
update=(e:InputEvent):void=>this.props.login[e.target.name]=e.target.value;
提交=(e:ButtonEvent):作废=>{
this.props.login.login();
e、 预防默认值();
}

您可以在react中这样做

handleEvent = (e: React.SyntheticEvent<EventTarget>) => {
  const simpleInput = (e.target as HTMLInputElement).value;
  //for simple html input values
  const formInput = (e.target as HTMLFormElement).files[0];
  //for html form elements
}
handleEvent=(e:React.SyntheticEvent)=>{
const simpleInput=(e.target作为HTMLInputElement).value;
//对于简单的html输入值
常量formInput=(e.target作为HTMLFormElement.files[0];
//对于html表单元素
}

对于那些正在寻找解决方案来获取事件并在
useState
上存储某些内容(在我的例子中是HTML 5元素)的人,以下是我的解决方案:

const[AnchoreElement,SetAnchoreElement]=useState(null);
const handleMenu=(事件:React.MouseEvent):void=>{
SetAnchoreElement(event.currentTarget);
};

我在
types.ts
文件中有以下内容,用于html输入、选择和文本区域:

export type InputChangeEventHandler = React.ChangeEventHandler<HTMLInputElement>
export type TextareaChangeEventHandler = React.ChangeEventHandler<HTMLTextAreaElement>
export type SelectChangeEventHandler = React.ChangeEventHandler<HTMLSelectElement>
然后使用它们:


const updateName: InputChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateBio: TextareaChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateSize: SelectChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
然后在标记上应用函数(用其他必要的道具替换
):


// ...

更新:
事件:React.ChangeEvent
对于提交:
event:React.FormEvent

对于click:
event:React.MouseEvent

ps。我的类型定义文件似乎有点过时,因为它没有显示通用事件界面。Nitzan Tomer的答案更好。什么是阅读所有常见事件类型的好地方?找不到任何位置。是否反应事件类型?它们都在.I get'name'中描述,但在类型'EventTarget&HTMLInputElements'(TS v2.4)上不存在。这仍然会给我带来以下错误。“类型“EventTarget&HTMLInputElement”上不存在属性“value”。@cmcdragokai我认为
e.key
只是键盘事件的一部分。this.props.login[target.name]=target.value???您是否在更改道具:oJust复制原始问题的行,以便答案对OP有意义。我想这取决于您想做什么(这很混乱),但对我来说,我必须将其更改为
导出类型InputChangeEventHandler=React.ChangeEvent
能够使用
事件.目标.值
。使用
changeventhandler
不允许使用
event.target
,因为它未定义。
import { InputChangeEventHandler } from '../types'

const updateName: InputChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateBio: TextareaChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateSize: SelectChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
<input onChange={updateName} ... />
<textarea onChange={updateName} ... />
<select onChange={updateSize} ... >
  // ...
</select>