ウェブサイト検索

reactjs - Typescript の input の onchange イベントの event.target.value


私の React と TypeScript のアプリでは、次のように使用しています:

onChange={(e) => data.motto = (e.target as any).value}

クラスの型定義を正しく行うにはどうすればよいですか?そうすれば、anyを使って型システムを無理に回避する必要がなくなります。

export interface InputProps extends React.HTMLProps<Input> {
...

}

export class Input extends React.Component<InputProps, {}> {
}

もし target: { value: string }; と書くと、私は次のようになります:

ERROR in [default] /react-onsenui.d.ts:87:18
Interface 'InputProps' incorrectly extends interface 'HTMLProps<Input>'.
  Types of property 'target' are incompatible.
    Type '{ value: string; }' is not assignable to type 'string'.

回答 #1

一般的に、イベントハンドラーは e.currentTarget.value を使用するべきです:

なぜそうなのかはここで読むことができます(「SyntheticEvent.target を一般化し、SyntheticEvent.currentTarget にはしない」に元に戻す)。

const onChange = (e: React.ChangeEvent<HTMLInputElement >) => {
  const newValue = e. currentTarget.value;
}

回答 #2

TypeScriptでの正しい使い方は

  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
        ...
        <input value={temperature} onChange={this.handleChange} />
        ...
    );
  }

授業を最後まで受けてください、理解するにはそれが良いです。

import * as React from "react";

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};


interface TemperatureState {
   temperature: string;
}

interface TemperatureProps {
   scale: string;

}

class TemperatureInput extends React.Component<TemperatureProps, TemperatureState> {
  constructor(props: TemperatureProps) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  //  handleChange(e: { target: { value: string; }; }) {
  //    this.setState({temperature: e.target.value});  
  //  }


  handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    // No longer need to cast to any - hooray for react!
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature} onChange={this.handleChange} />
      </fieldset>
    );
  }
}

export default TemperatureInput;

回答 #3

あなたは次のことを行うことができます:

import { ChangeEvent } from 'react';

const onChange = (e: ChangeEvent<HTMLInputElement>)=> {
   const newValue = e.target.value;
}

回答 #4

`ChangeEvent<HTMLInputElement>` は TypeScript の変更イベントの型です。方法は以下の通りです。

import { ChangeEvent } from 'react';

const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    setValue(event.target.value);
};

回答 #5

定義された型と共に onChange イベントを発火させることも、次のように(関数コンポーネントで)使用できます:

 const handleChange = (
    e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
  ) => {
        const name = e.target.name;
        const value = e.target.value;
};

回答 #6

`as HTMLInputElement` は私にはうまくいきます

回答 #7

私はこのようなものを使います:

import { ChangeEvent, useState } from 'react';


export const InputChange = () => {
  const [state, setState] = useState({ value: '' });

  const handleChange = (event: ChangeEvent<{ value: string }>) => {
    setState({ value: event?.currentTarget?.value });
  }
  return (
    <div>
      <input onChange={handleChange} />
      <p>{state?.value}</p>
    </div>
  );
}

回答 #8

あなたがInputPropsに追加しようとしたtargetは、React.FormEventにあるあなたが望んでいたtargetとは同じではありません

そこで、私が思いついた解決策は、次のようにイベント関連の型を拡張してターゲット型を追加することでした:

interface MyEventTarget extends EventTarget {
    value: string
}

interface MyFormEvent<T> extends React.FormEvent<T> {
    target: MyEventTarget
}

interface InputProps extends React.HTMLProps<Input> {
    onChange?: React.EventHandler<MyFormEvent<Input>>;
}

これらのクラスを手に入れたら、入力コンポーネントを次のように使用できます

<Input onChange={e => alert(e.target.value)} />

コンパイルエラーなしで。実際、上記の最初の二つのインターフェースを他のコンポーネントでも使用することができます。

回答 #9

子コンポーネントを使用する際、型はこのようにチェックします。

親コンポーネント:

export default () => {

  const onChangeHandler = ((e: React.ChangeEvent<HTMLInputElement>): void => {
    console.log(e.currentTarget.value)
  }

  return (
    <div>
      <Input onChange={onChangeHandler} />
    </div>
  );
}

子コンポーネント:

type Props = {
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
}

export Input:React.FC<Props> ({onChange}) => (
  <input type="tex" onChange={onChange} />
)

回答 #10

まだ言及されていないもう一つの方法は、受け取る props の代わりに onChange 関数の型を指定することです。React.ChangeEventHandler を使用すると:

const stateChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    console.log(event.target.value);
};

回答 #11

const handleChange = (
    e: ChangeEvent<HTMLInputElement>
  ) => {
    const { name, value } = e.target;
    this.setState({ ...currentState, [name]: value });
  };

このフォームコンポーネントのすべての input 要素にこれを適用することができます

回答 #12

const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const newValue = (event.target || event.currentTarget) as HTMLInputElement;
    return newValue.value;
}

関連記事