React-why event target value is undefined - reactjs

I am working on a shared component, which is an input textarea
The component is:
class TextBox extends React.Component {
constructor(props) {
...
const value = this.props.value;
this.state = {
value: value
}
}
handleChange(e, v) {
console.log("event: ", e);
this.setState({value: e.target.value}, () => {this.props.handleChange(e, v)});
}
render() {
const {
name
} = this.props;
const {
value
} = this.state;
return (
<div>
<h2>{name}</h2>
<textarea
value={value}
onChange={this.handleChange}
/>
</div>
);
}
}
Using this component:
const [comment, setComment] = useState('');
const handleChange = useCallback((e, v) => {
setComment(v);
}, [comment]);
....
<TextBox
name="comment"
value={comment}
handleChange={handleChange}
/>
The console log shows event.target.value is undefined
I have no idea why, can someone help? Thanks in advance
===update===
Thank you all! The problem is fixed

This should be target and value from the first parameter:
handleChange = (e) => {
console.log("event: ", e);
console.log("value: ", e.target.value);
this.setState({value: e.target.value}, () => {this.props.handleChange(e, v)});
}
Inside the above function:
e - Window.Event
e.target - <textarea> element in JS.
e.target.name will be the name attribute.
e.target.value will be the value attribute.
Also I'll suggest you to use Arrow Functions, else you might need to bind the function to this on the constructor, which is not being followed now-a-days.

You have to bind the handleChange function in constructor like below:
this.handleChange=this.handleChange.bind(this);
You can also use arrow function like this way:
handleChange=(e)=>{//...content here}
Also, there is no such parameter as v. The only parameter should be e.

Related

Convert Class component into a handleChange Hook

I'm wanting to convert this class component into a handleChange event that works in a function component. I'm not entirely sure that's possible, it may have to be a hook. I can't quite get the syntax right.
class CheckboxForm extends Component {
constructor(props) {
super(props);
this.state = { value: [] };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const input = event.target.value;
this.setState(
{
value: this.state.value.includes(input)
? this.state.value.filter((item) => item !== input)
: [...this.state.value, input],
},
() => {
console.log("CheckBox: ", this.state.value);
}
);
}
My attempt:
export const CheckboxHook = (props) => {
const [value, setValue] = useState([]);
const handleCheckbox = (event) => {
const input = event.target.value;
setValue(
value.include(input)
? value.filter((item) => item !== input)
: [value, input],
() => {
console.log("Checkbox: ", value);
}
);
};
};
Seems like you're trying to do something like this? You don't need any custom hooks for it - just useState and useEffect.
const CheckboxForm = (props) => {
const [checkedItems, setCheckedItems] = useState([]);
useEffect(() => {
// equivalent to passing a callback to `this.setState` in class component
console.log("Checked: ", checkedItems);
}, [checkedItems])
const handleCheckbox = (event) => {
const { value } = event.target;
// setting with hooks must use a callback
// if you need access to the previous value
setCheckedItems(items =>
items.includes(value)
? items.filter(item => item !== value)
: [...items, value]
);
};
return <form>
<label>a <input value="a" type="checkbox" onChange={handleCheckbox} /></label>
<label>b <input value="b" type="checkbox" onChange={handleCheckbox} /></label>
<label>c <input value="c" type="checkbox" onChange={handleCheckbox} /></label>
</form>
};
You can use a custom hook to wrap your handler logic and use it like:
const useHandleChange = () => {
const [value, setValue] = React.useState([]);
const handleChange = (event) => {
const input = event.target.value;
setValue(
{
value: value.includes(input)
? value.filter((item) => item !== input)
: [...value, input],
},
() => {
console.log("CheckBox: ", value);
}
);
};
return { value, handleChange };
};
// Usage
const { value, handleChange } = useHandleChange();
// In the render
<Input onChange={handleChange} value={value} />

how to get the checked value of a radio button using react

I have below radio button Component
import React from 'react';
import PropTypes from 'prop-types';
export default class RadioButton extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange = (event) => {
this.props.handleChange(event);
}
render() {
return (
<div>
<input type="radio" name="measureValue" value={this.props.value} onChange={this.handleChange} checked={true}/>
<label>{this.props.value}</label>
</div>
);
}
}
Im using this component as
handleRadioSelect = (event) =>{
this.setState({
selectedRadioValue : event.target.value
})
}
<RadioButton value="Fact" handleChange = { this.handleRadioSelect }/>
Now,I got the error as handleChnage is not a function.
to get value of checked, use the event.target.checked instead of event.target.value, so that:
handleRadioSelect = (event) =>{
this.setState({
radioChecked : event.target.checked
})
}
And your error appear because you need to use the arrow function to this.handleCheck (so you can pass in the event props) so that:
onChange={e => this.handleCheck(e)}
In this case, you do not need to bind it anymore and just use normal function for the handleCheck so that:
handleChange(event) {
this.props.handleChange(event);
}
This is how I normally approach it, hope that helps!
handleChange = (event) => {
let target = event.target;
let name = target.name;
let value = target.type === 'checkbox' ? target.checked : target.value;
this.setState({
[name] : value
})
}
Hope this helps

React controlled input cursor jumps

I am using React and have formatted a controlled input field, which works fine when I write some numbers and click outside the input field. However, when I want to edit the input, the cursor jumps to the front of the value in the input field. This only occur in IE, and not in e.g. Chrome. I've seen that for some programmers the cursor jumps to the back of the value. So I think the reason that my cursor is jumping to the front is because the value is aligned to the right instead of to the left in the input field. Here is a senario:
My first input is 1000
Then I want to edit it to 10003, but the result is
31000
Is there a way to controll that the cursor should not jump?
Here's a drop-in replacement for the <input/> tag. It's a simple functional component that uses hooks to preserve and restore the cursor position:
import React, { useEffect, useRef, useState } from 'react';
const ControlledInput = (props) => {
const { value, onChange, ...rest } = props;
const [cursor, setCursor] = useState(null);
const ref = useRef(null);
useEffect(() => {
const input = ref.current;
if (input) input.setSelectionRange(cursor, cursor);
}, [ref, cursor, value]);
const handleChange = (e) => {
setCursor(e.target.selectionStart);
onChange && onChange(e);
};
return <input ref={ref} value={value} onChange={handleChange} {...rest} />;
};
export default ControlledInput;
Taking a guess by your question, your code most likely looks similar to this:
<input
autoFocus="autofocus"
type="text"
value={this.state.value}
onChange={(e) => this.setState({value: e.target.value})}
/>
This may vary in behaviour if your event is handled with onBlur but essentially its the same issue. The behaviour here, which many have stated as a React "bug", is actually expected behaviour.
Your input control's value is not an initial value of the control when its loaded, but rather an underlying value bound to this.state. And when the state changes the control is re-rendered by React.
Essentially this means that the control is recreated by React and populated by the state's value. The problem is that it has no way of knowing what the cursor position was before it was recreated.
One way of solving this which I found to work is remembering the cursor position before it was re-rendered as follows:
<input
autoFocus="autofocus"
type="text"
value={ this.state.value }
onChange={(e) => {
this.cursor = e.target.selectionStart;
this.setState({value: e.target.value});
}
}
onFocus={(e) => {
e.target.selectionStart = this.cursor;
}
}
/>
This is my solution:
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
//get reference for input
this.nameRef = React.createRef();
//Setup cursor position for input
this.cursor;
}
componentDidUpdate() {
this._setCursorPositions();
}
_setCursorPositions = () => {
//reset the cursor position for input
this.nameRef.current.selectionStart = this.cursor;
this.nameRef.current.selectionEnd = this.cursor;
};
handleInputChange = (key, val) => {
this.setState({
[key]: val
});
};
render() {
return (
<div className="content">
<div className="form-group col-md-3">
<label htmlFor="name">Name</label>
<input
ref={this.nameRef}
type="text"
autoComplete="off"
className="form-control"
id="name"
value={this.state.name}
onChange={event => {
this.cursor = event.target.selectionStart;
this.handleInputChange("name", event.currentTarget.value);
}}
/>
</div>
</div>
);
}
}
export default App;
This is an easy solution. Worked for me.
<Input
ref={input=>input && (input.input.selectionStart=input.input.selectionEnd=this.cursor)}
value={this.state.inputtext}
onChange={(e)=>{
this.cursor = e.target.selectionStart;
this.setState({inputtext: e.target.value})
/>
Explanation:
What we are doing here is we save the cursor position in onChange(), now when the tag re-renders due to a change in the state value, the ref code is executed, and inside the ref code we restore out cursor position.
If you're using textarea, then here's the hook based on Daniel Loiterton's code using TypeScript:
interface IControlledTextArea {
value: string
onChange: ChangeEventHandler<HTMLTextAreaElement> | undefined
[x: string]: any
}
const ControlledTextArea = ({ value, onChange, ...rest }: IControlledTextArea) => {
const [cursor, setCursor] = useState(0)
const ref = useRef(null)
useEffect(() => {
const input: any = ref.current
if (input) {
input.setSelectionRange(cursor, cursor)
}
}, [ref, cursor, value])
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setCursor(e.target.selectionStart)
onChange && onChange(e)
}
return <textarea ref={ref} value={value} onChange={handleChange} {...rest} />
}
As (I think) others have mentioned, React will keep track of this if you make your changes synchronously. Unfortunately, that's not always feasible. The other solutions suggest tracking the cursor position independently, but this will not work for input types like 'email' which will not allow you to use cursor properties/methods like selectionStart, setSelectionRange or whatever.
Instead, I did something like this:
const Input = (props) => {
const { onChange: _onChange, value } = props;
const [localValue, setLocalValue] = useState(value);
const onChange = useCallback(
e => {
setLocalValue(e.target.value);
_onChange(e.target.value);
},
[_onChange]
);
useEffect(() => {
setLocalValue(value);
}, [value]);
// Use JSX here if you prefer
return react.createElement('input', {
...props,
value: localValue,
onChange
});
};
This allows you to delegate the cursor positioning back to React, but make your async changes.
My cursor jumped always to the end of the line. This solution seems to fix the problem (from github):
import * as React from "react";
import * as ReactDOM from "react-dom";
class App extends React.Component<{}, { text: string }> {
private textarea: React.RefObject<HTMLTextAreaElement>;
constructor(props) {
super(props);
this.state = { text: "" };
this.textarea = React.createRef();
}
handleChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
const cursor = e.target.selectionStart;
this.setState({ text: e.target.value }, () => {
if (this.textarea.current != null)
this.textarea.current.selectionEnd = cursor;
});
}
render() {
return (
<textarea
ref={this.textarea}
value={this.state.text}
onChange={this.handleChange.bind(this)}
/>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Here is my solution
const Input = () => {
const [val, setVal] = useState('');
const inputEl = useRef(null);
const handleInputChange = e => {
const { value, selectionEnd } = e.target;
const rightCharsCount = value.length - selectionEnd;
const formattedValue = parseInt(value.replace(/\D/g, ''), 10).toLocaleString();
const newPosition = formattedValue.length - rightCharsCount;
setVal(formattedValue);
setTimeout(() => {
inputEl.current.setSelectionRange(newPosition, newPosition);
}, 0);
};
return <input ref={inputEl} value={val} onChange={handleInputChange} />;
};
// Here is a custom hook to overcome this problem:
import { useRef, useCallback, useLayoutEffect } from 'react'
/**
* This hook overcomes this issue {#link https://github.com/reduxjs/react-redux/issues/525}
* This is not an ideal solution. We need to figure out why the places where this hook is being used
* the controlled InputText fields are losing their cursor position when being remounted to the DOM
* #param {Function} callback - the onChangeCallback for the inputRef
* #returns {Function} - the newCallback that fixes the cursor position from being reset
*/
const useControlledInputOnChangeCursorFix = callback => {
const inputCursor = useRef(0)
const inputRef = useRef(null)
const newCallback = useCallback(
e => {
inputCursor.current = e.target.selectionStart
if (e.target.type === 'text') {
inputRef.current = e.target
}
callback(e)
},
[callback],
)
useLayoutEffect(() => {
if (inputRef.current) {
inputRef.current.setSelectionRange(inputCursor.current, inputCursor.current)
}
})
return newCallback
}
export default useControlledInputOnChangeCursorFix
// Usage:
import React, { useReducer, useCallback } from 'react'
import useControlledInputOnChangeCursorFix from '../path/to/hookFolder/useControlledInputOnChangeCursorFix'
// Mimics this.setState for a class Component
const setStateReducer = (state, action) => ({ ...state, ...action })
const initialState = { street: '', address: '' }
const SomeComponent = props => {
const [state, setState] = useReducer(setStateReducer, initialState)
const handleOnChange = useControlledInputOnChangeCursorFix(
useCallback(({ target: { name, value } }) => {
setState({ [name]: value })
}, []),
)
const { street, address } = state
return (
<form>
<input name='street' value={street} onChange={handleOnChange} />
<input name='address' value={address} onChange={handleOnChange} />
</form>
)
}
For anybody having this issue in react-native-web here is solution written in TypeScript
const CursorFixTextInput = React.forwardRef((props: TextInputProps, refInput: ForwardedRef<TextInput>) => {
if(typeof refInput === "function") {
console.warn("CursorFixTextInput needs a MutableRefObject as reference to work!");
return <TextInput key={"invalid-ref"} {...props} />;
}
if(!("HTMLInputElement" in self)) {
return <TextInput key={"no-web"} {...props} />;
}
const { value, onChange, ...restProps } = props;
const defaultRefObject = useRef<TextInput>(null);
const refObject: RefObject<TextInput> = refInput || defaultRefObject;
const [ selection, setSelection ] = useState<SelectionState>(kInitialSelectionState);
useEffect(() => {
if(refObject.current instanceof HTMLInputElement) {
refObject.current.setSelectionRange(selection.start, selection.end);
}
}, [ refObject, selection, value ]);
return (
<TextInput
ref={refObject}
value={value}
onChange={event => {
const eventTarget = event.target as any;
if(eventTarget instanceof HTMLInputElement) {
setSelection({
start: eventTarget.selectionStart,
end: eventTarget.selectionEnd
});
}
if(onChange) {
onChange(event);
}
}}
{...restProps}
/>
)
});
The simplest and safest way of doing this is probably to save the cursor position before React renders the input and then setting it again after React finishes rendering.
import React, {ReactElement, useEffect, useRef} from "react";
/**
* Text input that preserves cursor position during rendering.
*
* This will not preserve a selection.
*/
function TextInputWithStableCursor(
props: React.InputHTMLAttributes<HTMLInputElement> & {type?: "text"}
): ReactElement {
const inputRef = useRef<HTMLInputElement>(null);
// Save the cursor position before rendering
const cursorPosition = inputRef.current?.selectionStart;
// Set it to the same value after rendering
useEffect(function () {
if (
typeof cursorPosition === "number" &&
document.activeElement === inputRef.current
) {
inputRef.current?.setSelectionRange(cursorPosition, cursorPosition);
}
});
return <input ref={inputRef} {...props} />;
}
If you faced an issue with the cursor jumping to the end after updating the input state and updating the cursor using refs -> I found a workaround for it by setting the cursor in Promise.resolve's microtask.
<input
value={value}
onChange={handleValueUpdate}
ref={inputRef}
/>
const handleValueUpdate = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
// ...
// some value handling logic
setValue(newValue)
const cursorPosition = getCursorPositionLogic();
/**
* HACK: set the cursor on the next tick to make sure that the value is updated
* useTimeout with 0ms provides issues when two keys are pressed same time
*/
Promise.resolve().then(() => {
inputRef.current?.setSelectionRange(cursorPosition, cursorPosition);
});
}
I know the OP is 5 years old but some are still facing the same kind of issue and this page has an high visibility on Google search.
Try by replacing :
<input value={...}
with
<input defaultValue={...}
This will solve most of the cases i've seen around there.
I tried all of the above solutions and none of them worked for me. Instead I updated both the e.currentTarget.selectionStart & e.currentTarget.selectionEnd on the onKeyUp React synthetic event type. For example:
const [cursorState, updateCursorState] = useState({});
const [formState, updateFormState] = useState({ "email": "" });
const handleOnChange = (e) => {
// Update your state & cursor state in your onChange handler
updateCursorState(e.target.selectionStart);
updateFormState(e.target.value);
}
<input
name="email"
value={formState.email}
onChange={(e) => handleOnChange(e)}
onKeyUp={(e) => {
// You only need to update your select position in the onKeyUp handler:
e.currentTarget.selectionStart = cursorState.cursorPosition;
e.currentTarget.selectionEnd = cursorState.cursorPosition;
}}
/>
Also, be aware that selectionStart & selectionEnd getters are not available on input fields of type email.

React Geosuggest doesn't update state

i'm trying to make a weather app, and using external component 'react-geosuggest'.
My problem is, when I update the input (SEE:onChange={this.onInputChange}), that function doesn't take my input, and don't change the state, i.e I get undefined.
What's interesting, i've set initialvalue to be New York, and on submit I get results, without changing input information, so problem lies in updating input information and passing it to function handleOnSubmit.
I've read docs about that component, but couldn't figure it out, it has same values as simple , but something doesn't work.
Thanks!
class SearchBar extends Component {
constructor() {
super()
this.state = {city: 'New York'};
}
onInputChange = (e) => {
this.setState({city: e.target.value});
}
handleOnSubmit = (e) => {
e.preventDefault();
this.props.fetchWeather(this.state.city);
this.setState({city: ''});
}
render () {
return (
<div>
<form onSubmit={this.handleOnSubmit}>
<Geosuggest
initialValue={this.state.city}
onChange={this.onInputChange}
types={['(cities)']}
/>
<button type="submit">Search</button>
</form>
</div>
</div>
);
}
}
Bind the event on the constructor, set the value attribute in the render and remove the setState to empty string that you are doing in the handleOnSubmit event. I am afraid this last one is what it makes not working when you change the input.
class SearchBar extends Component {
constructor(props) {
super(props);
this.state = {city: 'New York'};
this.onInputChange = this.onInputChange.bind(this);
}
onInputChange = (city) => {
this.setState({city: city});
}
handleOnSubmit = (e) => {
e.preventDefault();
this.props.fetchWeather(this.state.city);
}
render () {
return (
<div>
<form onSubmit={this.handleOnSubmit}>
<Geosuggest
initialValue={this.state.city}
value={this.state.city}
onChange={this.onInputChange}
types={['(cities)']}
/>
<button type="submit">Search</button>
</form>
</div>
</div>
);
}
}
Use e.currentTarget.value instead. See this question for more on this.
Also try this:
onChange={this.onInputChange.bind(this)}
If you'd like to be more concise you can write it this way:
<Geosuggest
initialValue={this.state.city}
onChange={(e)=> this.setState({city: e.currentTarget.value})}
types={['(cities)']}
/>
You can also get the value of selected address using onSuggestSelect:
<Geosuggest
ref={el=>this._geoSuggest=el}
placeholder="Search for address"
onSuggestSelect={this.onSuggestSelect}
country='us'
/>
Then access the components like so:
onSuggestSelect(suggest) {
if (!suggest.gmaps) {
return;
}
const components = suggest.gmaps.address_components;
const address = {
street: this.findAddressComponent(components, 'street_number', 'short_name') + ' ' + this.findAddressComponent(components, 'route', 'short_name'),
city: this.findAddressComponent(components, 'locality', 'short_name'),
state: this.findAddressComponent(components, 'administrative_area_level_1', 'short_name'),
zip: this.findAddressComponent(components, 'postal_code', 'short_name'),
}
this.setState({
address
});
}
findAddressComponent(components, type, version) {
const address = components.find(function(component) {
return (component.types.indexOf(type) !== -1);
});
return address[version];
}

Typescript input onchange event.target.value

In my react and typescript app, I use:
onChange={(e) => data.motto = (e.target as any).value}
How do I correctly define the typings for the class, so I wouldn't have to hack my way around the type system with any?
export interface InputProps extends React.HTMLProps<Input> {
...
}
export class Input extends React.Component<InputProps, {}> {
}
If I put target: { value: string }; I get :
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'.
Generally event handlers should use e.currentTarget.value, e.g.:
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
const newValue = e.currentTarget.value;
}
You can read why it so here (Revert "Make SyntheticEvent.target generic, not SyntheticEvent.currentTarget.").
UPD: As mentioned by #roger-gusmao ChangeEvent more suitable for typing form events.
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
}
the correct way to use in TypeScript is
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} />
...
);
}
Follow the complete class, it's better to understand:
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;
You can do the following:
import { ChangeEvent } from 'react';
const onChange = (e: ChangeEvent<HTMLInputElement>)=> {
const newValue = e.target.value;
}
ChangeEvent<HTMLInputElement> is the type for change event in typescript. This is how it is done-
import { ChangeEvent } from 'react';
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
we can also use the onChange event fire-up with defined types(in functional component) like as follows:
const handleChange = (
e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
) => {
const name = e.target.name;
const value = e.target.value;
};
as HTMLInputElement works for me
The target you tried to add in InputProps is not the same target you wanted which is in React.FormEvent
So, the solution I could come up with was, extending the event related types to add your target type, as:
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>>;
}
Once you have those classes, you can use your input component as
<Input onChange={e => alert(e.target.value)} />
without compile errors. In fact, you can also use the first two interfaces above for your other components.
I use something like this:
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>
);
}
When using Child Component We check type like this.
Parent Component:
export default () => {
const onChangeHandler = ((e: React.ChangeEvent<HTMLInputElement>): void => {
console.log(e.currentTarget.value)
}
return (
<div>
<Input onChange={onChangeHandler} />
</div>
);
}
Child Component:
type Props = {
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
}
export Input:React.FC<Props> ({onChange}) => (
<input type="tex" onChange={onChange} />
)
An alternative that has not been mentioned yet is to type the onChange function instead of the props that it receives. Using React.ChangeEventHandler:
const stateChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
console.log(event.target.value);
};
Here is a way with ES6 object destructuring, tested with TS 3.3.
This example is for a text input.
name: string = '';
private updateName({ target }: { target: HTMLInputElement }) {
this.name = target.value;
}
This works for me also it is framework agnostic.
const handler = (evt: Event) => {
console.log((evt.target as HTMLInputElement).value))
}
This is when you're working with a FileList Object:
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;
}}
Thanks #haind
Yes HTMLInputElement worked for input field
//Example
var elem = e.currentTarget as HTMLInputElement;
elem.setAttribute('my-attribute','my value');
elem.value='5';
This HTMLInputElement is interface is inherit from HTMLElement which is inherited from EventTarget at root level. Therefore we can assert using as operator to use specific interfaces according to the context like in this case we are using HTMLInputElement for input field other interfaces can be HTMLButtonElement, HTMLImageElement etc.
For more reference you can check other available interface here
Web API interfaces by Mozilla
Interfaces in External Node Modules by Microsoft
You no need to type if you do this:
<input onChange={(event) => { setValue(e.target.value) }} />
Because if you set a new value with the arrow function directly in the html tag, typescript will understand by default the type of event.
const handleChange = (
e: ChangeEvent<HTMLInputElement>
) => {
const { name, value } = e.target;
this.setState({ ...currentState, [name]: value });
};
you can apply this on every input element in the form component
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
}
And make sure you have "lib": ["dom"] in your tsconfig.
Convert string to number simple answer
<input
type="text"
value={incrementAmount}
onChange={(e) => {
setIncrementAmmount(+e.target.value);
}}
/>
import { NativeSyntheticEvent, TextInputChangeEventData,} from 'react-native';
// Todo in java script
const onChangeTextPassword = (text : any) => {
setPassword(text);
}
// Todo in type script use this
const onChangeTextEmail = ({ nativeEvent: { text },}: NativeSyntheticEvent<TextInputChangeEventData>) => {
console.log("________ onChangeTextEmail _________ "+ text);
setEmailId(text);
};
<TextInput
style={{ width: '100%', borderBottomWidth: 1, borderBottomColor: 'grey', height: 40, }}
autoCapitalize="none"
returnKeyType="next"
maxLength={50}
secureTextEntry={false}
onChange={onChangeTextEmail}
value={emailId}
defaultValue={emailId}
/>
const event = { target: { value: 'testing' } as HTMLInputElement };
handleChangeFunc(event as ChangeEvent<HTMLInputElement>);
this work for me.

Resources