React input onChange did'nt fire on same value - reactjs

Code:
function SingleInput(props: {value: string; onChanged: (value: string) => void}) {
const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
console.log("onChange fired with value", newValue) /*FIXME Убрать!*/;
props.onChanged(newValue);
},
[props.value, props.onChanged]
);
return <input type="text" maxLength={1} value={props.value} onChange={handleChange} />;
}
Problem:
Еhe onChange function is not called if I try to select an existing value and enter the same.
Example:
I type 1 on this component. Okay, onChange fired. Then I select this value by mouse and type 1 again - onChange didn't fired.
Question: What should I do so that the function is fired even on the same input?
Thanks!

You need to try with onInput event handler. It will capture event even if you are adding same value.
return <input type="text" maxLength={1} value={props.value} onChange={handleChange} onInput={handleChange} />;

You need to setup another state to store the all the uploaded files and clear the "onChange" - props.onChanged("");
i.e. like below so you can upload the same file and the actual file is located at "file"
const [file, setFile] = useState("")
const [inputValue, setInputValue] = useState("")
<input
type="file"
value={inputValue}
onChange={(e) => {
setFile(e.target.files[0])
setInputValue("")
}}
/>

Related

Dont set value in Form.Control

I have a new form for save data.
I use this code
const [validated, setValidated] = useState(false);
const [newInfo, setNewInfo] = useState({
name: ""
});
const handleChange = (event) => {
const { name, value }=event.target.value;
setNewInfo({
...newInfo,
[name]: value
});
console.log(newInfo.name)
};
and in Form.Control
<Form noValidate validated={validated}>
<Form.Group >
<Form.Label>Name</Form.Label>
<Form.Control required type="text" placeholder="Enter Name" value={newInfo.name}
onChange={handleChange} />
<Form.Control.Feedback type="invalid">Please choose a name.</Form.Control.Feedback>
</Form.Group>
<Button onClick={(e) => handleSubmit(e)} variant="primary">Submit</Button>
</Form>
When i type in input, run onchangehandle and event.target.value has value but dont set in input (input is empty) !!
when i change const [newInfo, setNewInfo] = useState(""); and set a string for it, it is ok .
setNewInfo() which is a setter is asynchronous, which means that at the time you console.log the state, it's not updated yet.
You can use useEffect to track for changes of state.
useEffect(() => {
console.log(newInfo);
},[newInfo.name);

React Typescript input onChange event type?

I'm trying to get text from a input element, setting it to state and then rendering it back into the input box. However I think my event typing is wrong? I've searched online and tried implementing many solutions but none have worked so far. Any help is appreciated.
my component:
import React, { ChangeEvent, ChangeEventHandler, useState } from "react";
export default function Unidirectionflow() {
const [state4, setState4] = useState("");
const [state5, setState5] = useState("");
let handleChange4 = (e: React.FormEvent<HTMLInputElement>): void => {
setState3((e.target as HTMLInputElement).value);
};
let handleChange5 = (event: ChangeEvent<HTMLInputElement>) => {
setState5(event.currentTarget.value);
};
return (
<main>
<input type="text" value={state4} onChange={() => handleChange4} />
<input type="text" value={state5} onChange={() => handleChange5} />
</main>
);
}
Typescript input onchange event.target.value
React TypeScript: Correct Types for onChange
Can't type in React TextField Input
https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/
You can do like this
export default function Unidirectionflow() {
const [states, setStates] = useState({
state3:'',
state4:''
})
const handleChange = (
e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
) => {
setStates({
...states,
[e.target.name]: e.target.value.trim(),
});
};
return (
<main>
<input type="text" name="state3" value={states.state3} onChange={handleChange} />
<input type="text" name="state4" value={states.state4} onChange={handleChange} />
</main>
);
};
onChange={handleChange}
See if this can help you!
Just do this:
handleChange = (event: Event) => {
const { value } = event.target as unknown as { value: string };
setState(value);
};
<input type='text' onChange={handleChange} />
And the squeegee lines will go away.
You have forgot to pass the event when calling the function
Try this
onChange={(e) => handleChange(e)}
Or
onChange={handleChange}
Code sandbox => https://codesandbox.io/s/dreamy-pateu-1mc6j?file=/src/App.tsx

Clearing TextBox After Button Click React

I have a React app in which I have a TextBox and a button. When I click on the button I want the TextBox value to be cleared. How can I achieve this without using a form?
const [name, setName] = useState('')
const handleChange = e => {
setName(e.target.value)
}
const handleSubmit = () => {
// clear the TextBox
}
<input type="text" onChange={handleChange} />
<button onClick={handleSubmit}></button>
Usually, in cases like this, input values are stored in state, which in your case it is called name
So you need to also map the input value to the state, then just set the value of name to nothing:
const [name, setName] = useState('')
const handleChange = (e) => {
setName(e.target.value)
}
const handleSubmit = () => {
setName('')
}
<input type="text" value={name} onChange={handleChange} />
<button onClick={handleSubmit}></button>
const [name, setName] = useState('')
const handleChange = (e) => {
setName(e.target.value)
}
const handleSubmit = () => {
setName('') // clear the TextBox
}
<input type="text" value={name} onChange = {handleChange} />
<button onClick = {handleSubmit}></button>

Input Field Onchange not allowing to type

I have a simple Input field which gets a value from onComponentMount. Now I want the user to be able to change value but Its not working. Here is my code:
componentDidMount = async () => {
const IPAddress = await publicIp.v4();
this.setState({ Client_IP: IPAddress })
}
eventHandler = () => (e: any) => {
e.persist()
this.setState((prevState: any) => ({
IPObject: {
...prevState.IPObject,
IPList: e?.target?.value
}
}));
}
<Input placeholder="IP address" required={true}
value={this.state.Client_IP} onChange={this.eventHandler()}></Input>
Change your input onChange to:
onChange={this.eventHandler}
When you use parantheses, you have to call it like an arrow function:
onChange={() => this.eventHandler()}
And make sure you change the field you want, in that eventHandler
Your code is constantly calling eventHandler function.
See here docs for eventHandling with JSX in react
The correct syntax will be
<Input placeholder="IP address" required={true} value={this.state.Client_IP} onChange={() => this.eventHandler()}></Input>
Or
<Input placeholder="IP address" required={true} value={this.state.Client_IP} onChange={this.eventHandler}></Input>

Set state for incremental numbers input

After months without reactjs I forgot how to solve this situation. I have a incremental input for numbers:
HTML:
<input
type="number"
value={stockQuantity}
defaultValue="1"
onChange={() => bookQuantity(stockQuantity)}
/>
React
const [stockQuantity, setStockQuantity] = useState(1);
const bookQuantity = (e) => {
setStockQuantity({ ...stockQuantity, [e.target.name]: e.target.value });
};
I just get errors I don't find the solution and I didn't find any previous work were I handle it.
Any idea?
You should define stockQuantity as an object initially:
const [stockQuantity, setStockQuantity] = useState({books: 1});
Then you can just setState in onChange event or create a separate function as you have already made.
You don't have to set the value prop
<input
type="number"
name="books"
defaultValue="1"
onChange={(e) => setStockQuantity({...stockQuantity, [e.target.name]: e.target.value})}
/>
You need to pass the event to your onChange handler and also add name to your input:
<input
type="number"
name="stockQuantity" // will be passed in e.target.name
value={stockQuantity}
defaultValue="1"
onChange={bookQuantity} // the same as onChange={(e) => bookQuantity(e)}
/>
I have found a little linear solution:
const [stockQuantity, setStockQuantity] = useState(1); // just numbers
const bookQuantity = (e) => {
setStockQuantity({ ...stockQuantity, [e.target.name]:
e.target.value });
};
HTML:
<input
type="number"
name="stock"
value={stockQuantity.books}
defaultValue="1"
onChange={bookQuantity}
// if you want you can use a placeholder
/>

Resources