How to Create Forms and Validate in ReactJS
4 min readMar 18, 2024
Form and Validations:
- Form Interactions and validations are managed by using event and data binding techniques.
- React uses event and data binding implicity without any additional libraries.
- React events are Synthetic Events that map to DOM events.
- React can also use style and class binding for validation styles.
Keyboard Events:
- onKeyUp
- onKeyDown
- onKeyPress
Key Properties:
- keyCode
- charCode
- which
- shiftKey
- altKey
- ctrlKey
- Users will not be able to enter value in the input field because ReactJS uses unidirectional data flow.
Data flow:
There are 2 two types of Data flow:
- Unidirectional
- Bidirectional
Bidirectional data flow:
- Most of the frameworks follow two-way data binding.
- This would allow for updates from both the end i.e., changes can be done from view to model and vice versa.
- In this approach state of the model could be mutated by both model and view, it would cause unpredictable data flow.
- Angular uses bidirectional data flow.
Unidirectional Data flow:
- In Unidirectional data flow pattern, the changes will be done only from component to view but not vice versa.
- This would prevent unpredictable data flow and easy to debug.
- React uses Unidirectional data flow.
There are 3 ways to handle Input or Form in React:
- By using Onchange()
- Using useRef hook
- Using FormData() constructor
Handling Form by using onChange() :
Note: I have used tailwind-css for styling the app.
App.jsx
import "./App.css";
import FormInput2 from "./components/FormInput2";
function App() {
return (
<div className="app">
<form>
<FormInput2 />
</form>
</div>
);
}
export default App;
App.css
.app{
height: 100vh;
width: 100vw;
padding: 0px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px solid green;
}
InputForm2.jsx
import { useState } from 'react';
import './formInput.css';
const FormInput2 = () =>{
const [username,setUsername] = useState("");
const [password, setPassword] = useState("");
console.log('Re-Rendered');
//console.log(password);
return(
<div className="form-input">
<input type="text" name="username" id="username" placeholder='username' onChange={e=> setUsername(e.target.value)}/>
<input type="password" name="password" id="password" placeholder='password' onChange={e=> setPassword(e.target.value)}/>
</div>
)
}
export default FormInput2;
form-input.css
.form-input{
padding: 1vw;
height:auto;
width: 20vw;
border: 1px solid red;
}
.form-input input{
width: 15vw;
padding: 0.5vw;
margin: 0.5vw;
}
useRef():
InputForm3.jsx
import { useRef, useState } from "react";
import "./formInput.css";
const FormInput3 = () => {
const usernameRef = useRef();
console.log('re-rendered');
const handleSubmit = (e) =>{
e.preventDefault();
console.log(usernameRef.current.value); // You will get username value at console
}
return (
<div className="form-input">
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
id="username"
placeholder="username"
ref={usernameRef}
/>
<input
type="password"
name="password"
id="password"
placeholder="password"
/>
<button>Submit</button>
</form>
</div>
);
};
export default FormInput3;
App.jsx
import "./App.css";
import FormInput3 from "./components/FormInput3";
function App() {
return (
<div className="app">
<FormInput3 />
</div>
);
}
export default App;
By FormData :
FormInput4.jsx
import { useRef, useState } from "react";
import "./formInput.css";
const FormInput4 = () => {
console.log('re-rendered');
const handleSubmit = (e) =>{
e.preventDefault();
const data = new FormData(e.target);
console.log(Object.fromEntries(data.entries()));
}
return (
<div className="form-input">
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
id="username"
placeholder="username"
/>
<input
type="password"
name="password"
id="password"
placeholder="password"
/>
<button>Submit</button>
</form>
</div>
);
};
export default FormInput4;
App.jsx
import "./App.css";
import FormInput4 from "./components/FormInput3";
function App() {
return (
<div className="app">
<FormInput4 />
</div>
);
}
export default App;
How to control multiple inputs:
Example 1:
FormByControlledComponent.jsx
import React, { useState } from "react";
const FormByControlledComponent = () => {
const [val, setVal] = useState({ name: "", email: "" });
const handleSubmit = (event) => {
event.preventDefault();
console.log(val);;
};
return (
<div className="w-full h-screen bg-zinc-100 flex flex-col justify-center items-center">
<h1 className="font-bold text-3xl underline">
Form by Controlled Components
</h1>
<form className="w-full mt-5 p-4" onSubmit={handleSubmit}>
<input
type="text"
name="name"
id="name"
placeholder="name"
className="border-2 mr-2 rounded"
onChange={(event) => setVal({ ...val, name: event.target.value })}
/>
<input
type="text"
name="email"
id="email"
placeholder="email"
className="border-2 mr-2 rounded"
onChange={(event) => setVal({ ...val, email: event.target.value })}
/>
<input
type="submit"
className="border-2 rounded-md bg-orange-500 px-2 py-1 text-white"
/>
</form>
</div>
);
};
export default FormByControlledComponent;
App.jsx
import { useState } from 'react'
import './App.css'
import FormByControlledComponent from './components/FormByControlledComponent'
function App() {
return (
<div className='w-full h-screen bg-blue-200'>
<FormByControlledComponent />
</div>
)
}
export default App
Example 2:
import React, { useRef } from 'react'
const Form = () => {
const name = useRef(null);
const email = useRef(null);
const handleSubmit = (event) =>{
event.preventDefault();
console.log(name.current.value);
console.log(email.current.value);
}
return (
<div className='flex flex-col justify-center items-center'>
<h1 className='font-bold text-3xl underline'>Form by useRef() hook</h1>
<form className='w-full mt-5 p-4' onSubmit={handleSubmit}>
<input ref={name} type="text" name="name" id="name" placeholder="name" className='border-2 mr-2 rounded'/>
<input ref={email} type="text" name="email" id="email" placeholder="email" className='border-2 mr-2 rounded' />
<input type="submit" className='border-2 rounded-md bg-orange-500 px-2 py-1 text-white' />
</form>
</div>
)
}
export default Form;
App.jsx
import './App.css'
import Form from './components/Form'
function App() {
return (
<div className='w-full h-screen bg-blue-200'>
<Form />
</div>
)
}
export default App
On both of the example, we are handling multiple inputs.
Thanks…