टाइपस्क्रिप्ट इनपुट onchange event.target.value


143

मेरी प्रतिक्रिया और टाइपस्क्रिप्ट ऐप में, मैं उपयोग करता हूं 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'.

जवाबों:


244

आम तौर पर घटना संचालकों का उपयोग करना चाहिए e.currentTarget.value, जैसे:

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

आप इसे यहाँ क्यों पढ़ सकते हैं ( वापस "SyntheticEvent.target जेनेरिक बनाएँ, नहीं SyntheticEvent.currentTarget।" )।

UPD: जैसा कि ChangeEventटाइपिंग इवेंट्स के लिए @ roger-gusmao अधिक उपयुक्त है।

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

17
यह बस काम नहीं करता है। मूल्य इंटरफ़ेस का एक गुण नहीं है EventTarget
tocqueville

1
बेशक इवेंटटार्ग नहीं, लेकिन HTMLInputElement का हिस्सा आप यहां पूरी परिभाषा देख सकते हैं github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/…
Yozit

1
ओह सॉरी, आपने इस्तेमाल किया currentTarget। उस मामले में हां, यह काम करता है, लेकिन सवाल थाtarget
टोकेविले

1
हाँ, आप सही हैं, लेकिन जैसा कि ज्यादातर मामलों में गलत का उपयोग करके github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 में उल्लेख किया गया है target। इसके अलावा, लक्ष्य Tको हमें सही ढंग से लिखने के लिए मजबूर नहीं करना है
योजि

1
यह मेरे लिए काम नहीं करता था, मुझे इवेंट को React.ChangeEvent<HTMLInputElement>फॉर्मवेंट के बजाय कास्ट करना था ।
Oblivionkey3

86

टाइपस्क्रिप्ट में उपयोग करने का सही तरीका है

  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
ध्यान दें: यह सुनिश्चित करने के प्रकार उपलब्ध हैं जोड़ने lib: ["dom"]के लिए compilerOptionsमेंtsconfig.json
जेम्स Conkling

1
@JamesConkling बहुत बहुत धन्यवाद!
अलेक्जेंड्रे रिवेस्ट

1
और अगर आपके पास कई इनपुट हैं, तो क्या आपको प्रत्येक के लिए एक पंक्ति बनाने की आवश्यकता है?
ट्रेवर वुड

यह सुनिश्चित करने का एक और तरीका है कि यह 'हैंडल' को उचित रूप से हैंडिल-चेंज फ़ंक्शन में सौंपा गया है, हैंडल-एरो फ़ंक्शन के रूप में हैंडल करना होगा जैसे कि हैंडलचेंज = (e: React.ChangeEvent <HTMLInputElement>) => {{यह .setState (...); }; ऐसा करने से, किसी को अब हैंडल फ़ंक्शन को बाँधने के लिए कंस्ट्रक्टर का उपयोग नहीं करना पड़ेगा।
tlavarea

कंस्ट्रक्टर और बाइंड पद्धति का उपयोग करने के बजाय 'इस' को संभालने का एक और तरीका यह होगा कि आप onChange प्रोप यानी onChange = {e => this.handleChange (e)} में तीर फंक्शन का उपयोग करें
tlavarea

12

as HTMLInputElement मेरे लिये कार्य करता है


9

targetआप में जोड़ने की कोशिश की InputPropsही नहीं है targetआप चाहते थे, जिसमें हैReact.FormEvent

इसलिए, मैं अपने लक्ष्य प्रकार को जोड़ने के लिए घटना से संबंधित समाधान को बढ़ा सकता हूं, जैसे:

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)} />

संकलन त्रुटियों के बिना। वास्तव में, आप अपने अन्य घटकों के लिए पहले दो इंटरफेस का भी उपयोग कर सकते हैं।


मान प्रकार स्ट्रिंग नहीं है!
रोजर गुस्माओ

7

भाग्यशाली मैं एक समाधान मिल आप ऐसा कर सकते हैं

'रिएक्ट' से {ChangeEvent} आयात करें;

और फिर कोड लिखें जैसे: e:ChangeEvent<HTMLInputElement>


2

यहां एक तरीका है ईएस 6 ऑब्जेक्ट डिस्ट्रक्ट्यूरिंग, टीएस 3.3 के साथ परीक्षण किया गया।
यह उदाहरण एक पाठ इनपुट के लिए है।

name: string = '';

private updateName({ target }: { target: HTMLInputElement }) {
    this.name = target.value;
}

1

जब आप किसी FileListऑब्जेक्ट के साथ काम कर रहे हों :

onChange={(event: React.ChangeEvent<HTMLInputElement>): void => {
  const fileListObj: FileList | null = event.target.files;
  if (Object.keys(fileListObj as Object).length > 3) {
    alert('Only three images pleaseeeee :)');
  } else {
    // Do something
  }

  return;
}}

1
  function handle_change(
    evt: React.ChangeEvent<HTMLInputElement>
  ): string {
    evt.persist(); // This is needed so you can actually get the currentTarget
    const inputValue = evt.currentTarget.value;

    return inputValue
  }

और सुनिश्चित करें कि आप "lib": ["dom"]में है tsconfig


1

चाइल्ड कंपोनेंट का उपयोग करते समय हम इस प्रकार की जाँच करते हैं।

मूल घटक:

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} />
)

0

एक विकल्प जिसका उल्लेख अभी तक नहीं किया गया है, वह है कि इसे प्राप्त होने वाले प्रॉप्स के बजाय ऑनक्रॉस फ़ंक्शन टाइप करें। React.ChangeEventHandler का उपयोग करना:

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

-1

धन्यवाद @haind

हां HTMLInputElementइनपुट क्षेत्र के लिए काम किया

//Example
var elem = e.currentTarget as HTMLInputElement;
elem.setAttribute('my-attribute','my value');
elem.value='5';

यह HTMLInputElementवह इंटरफ़ेस है HTMLElementजो EventTargetमूल स्तर से विरासत में मिला है। इसलिए हम asसंदर्भ के अनुसार विशेष इंटरफेस का उपयोग करने के लिए ऑपरेटर का उपयोग करने पर जोर दे सकते हैं जैसे कि इस मामले में हम HTMLInputElementइनपुट क्षेत्र के लिए उपयोग कर रहे हैं अन्य इंटरफेस हो सकते हैं HTMLButtonElement, HTMLImageElementआदि।

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

अधिक संदर्भ के लिए आप यहां अन्य उपलब्ध इंटरफेस की जांच कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.