Reactjs Get Input time value onchange - reactjs

How do I get the value of an input type time in reactjs functional component.
Here is an example I am getting.
<input type="time" onChange={(e) => console.log(e)} className="app-time" min="00:00" max="23:59" value={value} />
On console log event is printing but there is no target value on the console.How can I get the value in HH:mm format?

The value can be accessed via e.currentTarget.value.
Since it's a controlled component you'd want to call setValue in your change handler to make sure the input gets updated.

Just use event.target.value like in the code below. You can also set the step attribute to a value in seconds to control how granular the changes are. You can read more about time inputs on MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time
<script src="https://unpkg.com/react#17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#17.0.2/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone#7.15.8/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel" data-type="module" data-presets="typescript,react">
const {useState} = React;
function Example (): React.ReactElement {
const [value, setValue] = useState('00:00');
return (
<input
type="time"
onChange={ev => setValue(ev.target.value)}
min="00:00"
max="23:59"
step="60"
value={value}
/>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
</script>

Related

is there a way to do something similar to document.getelementbyid() in this situation

I am working on a project where i try to implement a search function. My first step is to make sure that all input is set to lower case to make SQL calls easier. However i have stumbled upon a problem that i am struggling to fix. I do not know how to do a document.getElementById('') in react typescript. I am quite new to these languages and have tried the solutions found here (How to do something like document.getElementById().value in typescript?) but this does not seem to get the data stored in my element.
So im wondering how can i get the input in the searchbar into the variable defaultText.
here is the element that i want to grab
<Row><input type="search" id="form1" onChange={this.input} placeholder="Søk etter oppskrift.."/></Row>
here is the function which i attempt to set the input to lower case
input(){
const defaultText:string = (document.getElementById('form1') as HTMLInputElement).value;
console.log (defaultText);
// To convert Lower Case
let lowerCaseText = defaultText.toLowerCase();
console.log(lowerCaseText);
}
The outcome from both 'console.log' is simply an empty row
You don't need to use native javascript selectors for this. You can just use the onChange method, first parameter will give you the ChangeEvent for the input change. You can get the value simply by event.target.value (assuming the parameter is taken as event).
Furthermore you can save this value to the state using useState.
See the changed code.
const [inputValue, setInputValue] = useState("");
function onChange(event: React.ChangeEvent<HTMLInputElement>){
const defaultText:string = event.target.value;
// To convert Lower Case
let lowerCaseText = defaultText.toLowerCase();
// You can either save lowerCaseText or defaultText here
setInputValue(defaultText):
}
<Row><input type="search" id="form1" onChange={onChange} placeholder="Søk etter oppskrift.." value={inputValue}/></Row>
You should use state, it will be the best way to handle it, and it's "the React way"
See React Docs
Higher up in the component you will need to declare the initial value of your input:
const [inputValue, setInputValue] = React.useState("");
// In typescript you can also do the following:
// const [inputValue, setInputValue] = React.useState<string>("");
Later on you will need to use the state, as well as manage when it is updated:
<Row>
<input
type="search"
id="form1"
value={inputValue}
onChange={(event) => {
setInputValue(event.target.value)
}}
placeholder="Søk etter oppskrift.."
/>
</Row>
Converting my comment to an answer to give an example.
You should use an useState to remember the value of the input. Set it using value. Then in your onChange function, set it to lower before calling the set function.
Demo without typescript:
const { useState, useEffect } = React;
function App() {
const [value, setValue] = useState('');
const onInputValue = (e) => {
setValue(e.target.value.toLowerCase())
};
return (
<input type="search" value={value} id="form1" onChange={onInputValue} placeholder="Søk etter oppskrift.."/>
);
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Is there a way to restrict your input element to only accept videos?

I have an input element with type set to file which I am using to upload files. The problem is it also accepts images but I don't want that. I only want videos to be accepted. Is there a way to go about it?
<input
type="file"
id="file"
ref={inputFile}
onChange={(event) => handleVideoUpload(event.target.files[0])}
}
The accept attribute on the input should do the job:
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
Just use accept prop
If required an extra step to validate -
you can check the condition before submitting / posting by using File type - MIME of video
a sample e.g.
const { useRef } = React;
const App = () => {
const fileRef = useRef(null);
const handleVideoUpload = (file) => {
if(!file.type.includes("video")){
alert("not a video and don't submit, just return")
return
}else{
alert("It's a video ... proceed submitting")
}
}
return (
<div>
<input
type="file"
id="file"
accept="video/*"
ref={fileRef}
onChange={(event) => handleVideoUpload(event.target.files[0])}
/>
</div>
);
};
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

How to update a form's input text state immediately in React using setState()

const [text, setText] = useState('');
const handleTextChange = (e) => {
setText(e.target.value);
}
// Inside a form
<input onChange={handleTextChange} value={text} type="text" />
I'm trying to do something very simple but can't quite get it to work properly. From the code above, I have text and setText to store and update the state, and a function handleTextChange which gets called by the input field's onChange method.
I know that setState() is async so wont update immediately, however, If i need access to the updated result immediately how can I get it? I've read that useEffect hook can be used to do this but I can't figure out how I need to use it. If there is another way to accomplish this then please share.
The main objective is to get the "updated value of the text state variable" as the user is typing in the input field.
I don't think useEffect is appropriate for what you are trying to do
function App({ onSubmit }) {
const [text, setText] = React.useState("")
return <form onSubmit={e => onSubmit(text)}>
<input
onChange={e => setText(e.target.value)}
value={text}
placeholder="enter a comment"
/>
<button
type="submit"
disabled={text.length >= 10}
children="disabled at 10 chars"
/>
<p>{Math.max(0, 10 - text.length)} characters remaining...</p>
</form>
}
ReactDOM.render(<App onSubmit={alert} />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
you can use e.target.value for the latest value unless you really want to use a state variable then you can wrap it up in useEffect but there does not seem to be a need for it :)
you can just use disabled={text.length===10}

React states are not being saved to the JavaScript array

I am learning about states in React, and below is an exercise to create a to-do list.
I capture the state of each inputted "item" in the to-do list and add them to an "items" array.
Then, each element in the "items" array is rendered using HTML.
I don't understand why I can't just push each item into a normal JavaScript array? After submitting the form, I log the "items" array. However, the "items" array only has 1 element, no matter how many times I submit the form. It seems like previous values are disappearing every time.
I solved the problem by using a React state that is an array. But I still don't understand why I can't use a JS array. Any explanations/resources would be greatly appreciated!
function App() {
const items = [];
//const [items, setItems] = React.useState([]);
const [inputText, setInputText] = React.useState("");
function handleSubmit(event) {
items.push(inputText);
console.log(items);
//setItems((prevValue) => {
// return [...prevValue, inputText];
//});
event.preventDefault();
}
function handleChange(event) {
setInputText(event.target.value);
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<form className="form" onSubmit={handleSubmit}>
<input type="text" value={inputText} onChange={handleChange} />
<button type="submit">
<span>Add</span>
</button>
</form>
<div>
<ul>
{items.map((item) => {
return <li>{item}</li>;
})}
</ul>
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
You have to define the let items = []; outside the function. Because in react each component reloaded on state update. so it will re-assigned to empty array. Make sure you define it using let not const
You can use the react hook useCallback to prevent items re-rendering every time state changes const items = useCallback([], [])

Component design hierearchy in React

I have recently started learning React. I want to create two components - Input and Display. Input has a textfield and a button. When I type something and submit the button, the value of the textfield should be passed as a prop to Display and the Display should output the value.
How to approach the design? What is the component hierarchy?
You will need to 'lift up' the value from the text input to the display prop via it's shared ancestor component.
Here is an example of 'lifting up' state with useState in the functional style:
const Input = ({ setValue }) => {
return <input onChange={(event) => setValue(event.target.value)} />
}
const Display = ({ value }) => {
return <div>{value}</div>
}
const Parent = () => {
const [value, setValue] = React.useState('')
return <div>
<Input setValue={setValue} />
<Display value={value} />
</div>
}
ReactDOM.render(<Parent />, document.getElementById('app'))
<script crossorigin src="https://unpkg.com/react#16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js"></script>
<div id="app" />
If you provide what you have at the moment, then it'll be easier to answer; otherwise I'll just be writing the whole code instead of letting you learn.
One way is to implement a callback function that sets the state in Display with text field's value when Input button is clicked. Display should be the one passing this function as a prop to Input. Input calls this function when button is clicked with the text field's value.
Then whatever is rending Display's state will output the value appropriately.

Resources