How to get the initial validation message from Input in React? - reactjs

I have a number input (using Material UI Input) with min max set. If a user types in a number higher than the max, I can get the validation message from event.target.validationMessage during onChange event. This works so far when a user is inputting on an empty number input field.
Now say I initialised my state with an initial value that is higher than the max already, how and when should I access the event.target.validationMessage as this is before the user input (i.e. no onChange event yet)?
Here is an example: https://codesandbox.io/s/cocky-shamir-1fg7h
import { useState } from "react";
import ReactDOM from "react-dom";
const Input = (props) => {
const [msg, setMsg] = useState();
return (
<div>
<input
type="number"
min="1"
max="10"
defaultValue={props.defaultValue}
onChange={(event) => setMsg(event.target.validationMessage)}
></input>
<span>{msg}</span>
</div>
);
};
const App = () => {
return (
<div>
<label>Type 0 below to see the error message</label>
<Input defaultValue="1" />
<label>Should show error message straight away</label>
<Input defaultValue="100" />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));

This should do the trick (or at least be a start):
import { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const Input = (props) => {
const [msg, setMsg] = useState();
// the added part
const ref = useRef();
useEffect(() => {
if (ref.current.validationMessage) setMsg(ref.current.validationMessage);
}, [ref]);
// the added part
return (
<div>
<input
ref={ref}
type="number"
min="1"
max="10"
defaultValue={props.defaultValue}
onChange={(event) => setMsg(event.target.validationMessage)}
></input>
<span>{msg}</span>
</div>
);
};
const App = () => {
return (
<div>
<label>Type 0 below to see the error message</label>
<Input defaultValue="1" />
<label>Should show error message straight away</label>
<Input defaultValue="100" />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
codesandbox
Remember that target is basically a ref to your input.

Related

Enter any mathematical expression on the textbox and click the button, the result of th expression will be shown in alert window. in reactjs eg2+3-1

import { useState } from "react";
import ReactDOM from 'react-dom/client';
function MyForm() {
const [name, setName] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
var a=parseInt(name)
console.log(a)
alert(name);//need to alert message evaluate the mathematical expressions
console.log(name)
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<input type="submit" />
</form>
)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyForm/>);
in this code i need to pass the input value to the function and evaluate or do mathematical expression by result showing to the alert box
import { useState } from "react";
import ReactDOM from 'react-dom/client';
function MyForm() {
const [name, setName,] = useState("");
function handleClick(){
var y=addbits("h");
console.log("this is the value passed from addbits",h)
alert(h)
}
function addbits(name) {
var total = 0;
name = name.match(/[+\-]*(\.\d+|\d+(\.\d+)?)/g) || [];
while (name.length) {
total += parseFloat(name.shift());
}
return total;
}
var h=addbits(name)
console.log(h)
return (
<div>
<h1>Hit the click Button :::</h1>
<form >
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</form>
<button onClick={handleClick}>Click</button>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyForm />);

Radio button with form in Function Component (React) =>get Warning from the Console

I try to collect data from inputs and pass it down to next pages, after adding radio button in the form, the code works fine, however, the Browser Console on Chrome gives me warnings like following:
Warning: You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.
What does that mean? And how to solve it?
(I'm new to the React. Appreciate for your time)
the following is the code:
import {useLocation} from 'react-router-dom';
import { useState } from "react";
import { useNavigate } from "react-router-dom";
const Second = () => {
const navigate = useNavigate();
const location = useLocation();
const contact=location.state;
const [name, setName] = useState("");
const [wording, setWording] = useState("");
const handleSecSubmit = (e) => {
e.preventDefault();
const contacttotal={
...contact,
...{name},
...{wording}
};
console.log(contacttotal);
navigate("/final", { state: { contacttotal } });
}
return (
<div className="Second">
<h1>This is Second Input Page</h1>
<form autoComplete="on" onSubmit={handleSecSubmit}>
<dd>Name</dd>
<input
type="text"
value={name}
onChange={(e) =>
setName(e.target.value)
}
required
></input>
<dd>Wording</dd>
<div>
<div onChange={(e) => setWording(e.target.value)}>
<label><input
type="radio"
value='United States'
name="wording"
checked={wording === "United States"}
/>United States</label>
<label><input
type="radio"
value='British'
name="wording"
checked={wording === "British"}
/>British</label>
</div>
</div>
<br/>
<button>submit</button>
</form>
</div>
);
}
export default Second;
Simply add onChange event to every input.
<input
type="radio"
value='United States'
name="wording"
checked={wording === "United States"}
onChange={(e) => setWording(e.target.value)}
/>
And remove it from the div. It's not the best idea to use onChange event on other elements than input, textarea or select.

Not working onChange in react-input-mask (custom input)

Not working onChange in react-input-mask (custom input)
I am not using any libraries as input, but for some reason onChange dont work...
<InputMask
onChange={(e) => console.log(e.target.value)} // dont work...
disabled={true}
>
{(props) => {
return <input type="text" />;
}}
</InputMask>
you need to pass props inside custom input
import React from "react";
import { useState } from "react";
import ReactDOM from "react-dom";
import InputMask from "react-input-mask";
import "./styles.css";
const App = () => {
const [inputValue, setInputValue] = useState("");
const onHandleChange = (event) => {
console.log(event.target.value);
setInputValue(event.target.value);
};
return (
<div className="App">
<h1>react-input-mask with Input from Ant D</h1>
<h2>
Throwing error: react-input-mask: the following props should be passed
to the react-input-mask's component and should not be altered in
children's function: disabled
</h2>
<InputMask mask="99/99/9999" value={inputValue} onChange={onHandleChange}>
{(inputProps) => (
<input {...inputProps} type="tel" className="" disableUnderline />
)}
</InputMask>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Next js send form data to parent page

I create a simple page called lucky number
pages/lucky.js
import finder from '../../hooks/use-finder'
import NumberForm from '../components/number-form'
export default function LuckyNumber() {
const { data } = finder(number)
console.log(data)
return (
<>
<h1>Lucky Number</h1>
<NumberForm />
</>
)
}
export default function NumberForm() {
return (
<>
<form>
<label>
Number:
<input type="text" name="number" />
</label>
<input type="submit" value="Submit" />
</form>
</>
)
}
where NumberForm is a form where user can just input a number ex: 12345. Once use submits the form, I want to pass that number to my hook in the page finder(number) so I can check to see if that number is in my lucky list of numbers.
How can I pass the number that user submits to the page?
I think you can use parent state and send the setState to the child to update it i.e.
pages/lucky.js
import React, { useState } from 'react'
import finder from '../../hooks/use-finder'
import NumberForm from '../components/number-form'
export default function LuckyNumber() {
const [number, setnumber] = useState(0);
const { data } = finder(number)
console.log(data)
return (
<>
<h1>Lucky Number</h1>
<NumberForm onChange={setnumber} />
</>
)
}
export default function NumberForm({ onChange }) {
const [number, setnumber] = useState(0);
const handleChange = (event)=>{
setNumber(event?.target?.value)
}
const handleSubmit = (event)=>{
event.preventDefault();
onChange(number)
}
return (
<>
<form>
<label>
Number:
<input type="text" name="number" value={number} onChange={ handleChange } />
</label>
<input type="submit" value="Submit" onClick={ handleSubmit } />
</form>
</>
)
}

How to do validation using useRef()

How do I validate input box value using useRef .
Initial validation is not required once user clicks on input box and comes out then it should validate if input box is empty it should show input box cannot be empty.
Codesandbox Link
code i tried. using onBlur
export default function App() {
const name = React.useRef("");
const nameBlurData = (name) => {
console.log("name", name);
};
return (
<div className="App">
<form>
<input
onBlur={() => nameBlurData(name.current.value)}
type="text"
ref={name}
placeholder="Enter First Name"
/>
// show error message here
</form>
</div>
);
}
You can use "useRef" to validate the value of an input field.
No need to use "useState".
Below code is a basic implementation of OP's question
You can replace the "console.log" with your alert component.
import { useRef } from "react";
const ComponentA = () => {
const emailRef = useRef(null);
const passwordRef = useRef(null);
const onBlurHandler = (refInput) => {
if (refInput.current?.value === "") {
console.log(`${refInput.current.name} is empty!`);
}
}
return (
<form>
<input ref={emailRef} onBlur={onBlurHandler.bind(this, emailRef)} />
<input ref={passwordRef} onBlur={onBlurHandler.bind(this, passwordRef)} />
<form/>
)
}
Link to "useRef"
Note: Not tested, code typed directly to SO's RTE
You can use a local state and conditionally render an error message like this:
const [isValid, setIsValid] = useState(true)
const nameBlurData = (name) => {
setIsValid(!!name);
};
return (
<div className="App">
<form>
<input
onBlur={() => nameBlurData(name.current.value)}
type="text"
ref={name}
placeholder="Enter First Name"
/>
{!isValid && <span> input must not be empty </span> }
</form>
Note that you don't really need a ref in this case, you can just use the event object like:
onBlur={(event) => nameBlurData(event.target.value)}
You need to use useState hook to update the value of the name property. Using ref is not ideal here.
Live demo https://stackblitz.com/edit/react-apqj86?devtoolsheight=33&file=src/App.js
import React, { useState } from 'react';
export default function App() {
const [name, setName] = useState('');
const [hasError, setError] = useState(false);
const nameBlurData = () => {
if (name.trim() === '') {
setError(true);
return;
}
setError(false);
};
return (
<div className="App">
<form>
<input
onBlur={nameBlurData}
type="text"
value={name}
onChange={e => setName(e.target.value)}
placeholder="Enter First Name"
/>
{hasError ? <p style={{ color: 'red' }}>Name is required</p> : null}
</form>
</div>
);
}

Resources