How to convert Class component to function on react - javascript

I have a customer feedback page or rather a contact page. There are a few in there. The page is written in JavaScript, React in the class component. I want to convert it to a functional component.
Below I will throw source code off the page
import React, { Component } from "react";
import { Button, Form, FormGroup, Label, Input, FormText } from "reactstrap";
import axios from "axios";
class Contacts extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
subject: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange = e => {
this.setState({ [e.target.name]: e.target.value });
//console.log(`${e.target.name}:${e.target.value}`);
};
async handleSubmit(e) {
e.preventDefault();
const { name, email, subject } = this.state;
const form = await axios.post("/api/form", {
name,
email,
subject
});
}
render() {
return (
<Form className="col-xs-12 col-md-6" onSubmit={this.handleSubmit}>
<FormGroup>
<Label for="name">name:</Label>
<Input type="text" name="name" onChange={this.handleChange} />
</FormGroup>
<FormGroup>
<Label for="exampleEmail">Email:</Label>
<Input type="email" name="email" onChange={this.handleChange} />
</FormGroup>
<FormGroup>
<Label for="subject">Subject:</Label>
<Input type="textarea" name="subject" onChange={this.handleChange} />
</FormGroup>
<Button>Submit</Button>
</Form>
);
}
}
export default Contacts;

1- first create a functional component like below:
2- add some hooks for the state:
3- Refactor functions in a new way:
4- At the end add the return section.
Finally you have something like this:
export default function Contacts() {
const [state, setState] = useState({
name: '',
email: '',
subject: '',
});
const handleChange = (e) => {
setState({ [e.target.name]: e.target.value });
//console.log(`${e.target.name}:${e.target.value}`);
};
const handleSubmit = async (e) => {
e.preventDefault();
const { name, email, subject } = state;
const form = await axios.post('/api/form', {
name,
email,
subject,
});
};
return (
<Form className="col-xs-12 col-md-6" onSubmit={handleSubmit}>
<FormGroup>
<Label for="name">name:</Label>
<Input type="text" name="name" onChange={handleChange} />
</FormGroup>
<FormGroup>
<Label for="exampleEmail">Email:</Label>
<Input type="email" name="email" onChange={handleChange} />
</FormGroup>
<FormGroup>
<Label for="subject">Subject:</Label>
<Input type="textarea" name="subject" onChange={handleChange} />
</FormGroup>
<Button>Submit</Button>
</Form>
);
}

const Contacts = (props) => {
const [name, setName] = useState();
const [email, setEmail] = useState();
const [subject, setSubject] = useState();
const handleChange = useCallback((setState, event) => {
setState(event.target.value);
}, []);
const handleSubmit = useCallback(async () => {
const response = await axios.post("/api/form", {
name,
email,
subject
});
console.log(response)
}, [name, email, subject]);
return (
<Form className="col-xs-12 col-md-6" onSubmit={handleSubmit}>
<FormGroup>
<Label for="name">name:</Label>
<Input type="text" name="name" onChange={handleChange.bind(null, setName)} />
</FormGroup>
<FormGroup>
<Label for="exampleEmail">Email:</Label>
<Input type="email" name="email" onChange={handleChange.bind(null, setEmail)} />
</FormGroup>
<FormGroup>
<Label for="subject">Subject:</Label>
<Input type="textarea" name="subject" onChange={handleChange.bind(null, setSubject)} />
</FormGroup>
<Button>Submit</Button>
</Form>
);
}

Related

Form not submitting properly using Reactjs

I am working with Reacjs/nextjs,Right now i am trying to submit "login form" i am getting alert but page is also reloading,I just want page should not reload,Where i am wrong ? Here is my current code in "index.tsx"
import React from 'react';
import axios from 'axios';
const LoginForm = () => {
const [formValue, setformValue] = React.useState({
email: '',
password: ''
});
const handleSubmit = (event) => {
alert("its workinggg");
// we will fill this in the coming paragraph
}
const handleChange = (event) => {
setformValue({
...formValue,
[event.target.name]: event.target.value
});
}
return (
<form onSubmit={handleSubmit}>
<p>Login Form</p>
<input
type="email"
name="email"
placeholder="enter an email"
value={formValue.email}
onChange={handleChange}
/>
<input
type="password"
name="password"
placeholder="enter a password"
value={formValue.password}
onChange={handleChange}
/>
<button
type="submit"
>
Login
</button>
</form>
)
};
export default LoginForm;
Use preventDefault method to prevent default reload.
It works with all events which have default action.
const LoginForm = () => {
const [formValue, setformValue] = React.useState({
email: '',
password: ''
});
const handleSubmit = (event) => {
event.preventDefault() // <----- HERE
alert("its workinggg");
// we will fill this in the coming paragraph
}
const handleChange = (event) => {
setformValue({
...formValue,
[event.target.name]: event.target.value
});
}
return (
<form onSubmit={handleSubmit}>
<p>Login Form</p>
<input
type="email"
name="email"
placeholder="enter an email"
value={formValue.email}
onChange={handleChange}
/>
<input
type="password"
name="password"
placeholder="enter a password"
value={formValue.password}
onChange={handleChange}
/>
<button
type="submit"
>
Login
</button>
</form>
)
};

how to add validation to a reactjs form

I have developed a registration form and I tried using validation format but it is not working. I don't know how and where to code a function for it and apply it. please help me how to do it. I will attach the code i have done till now.
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = () => {
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form">
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button onClick={postData} type='submit'>Submit</Button>
</Form>
</div>
)
}
There are good libraries out there, that can help you with form validation before allowing a user to submit the form.
One such library could be formik together with Yup.
This is how I do client side form validation on my forms:
Login schema (made with Yup):
import * as Yup from 'yup';
const loginSchema = Yup.object().shape({
username: Yup.string()
.min(3, 'Minimum 3 chars')
.max(50, 'Max 50 chars')
/* password: Yup.string()
.min(6, 'Minimum 6 chars')
.max(50, 'Max 50 chars')
*/
});
Login component:
export const Login = () => {
const [loading, setLoading] = useState(false);
const formik = useFormik({
initialValues: {
username: ''
},
validationSchema: loginSchema,
onSubmit: async (values, {setStatus, setSubmitting}) => {
setLoading(true);
setStatus(null);
try {
// Call your API function to post to the backend here
// You can access your form values in the "values" parameter
setLoading(false);
} catch (error) {
console.error(error);
setStatus('User not found');
setSubmitting(false);
setLoading(false);
}
}
});
}
return (
<form
onSubmit={formik.handleSubmit}
className={'auth-form-wrapper'}
>
{/* begin::Heading */}
<div className={'auth-form-header'}>
<h1>Log in</h1>
<div className={'auth-error-message-container'}>
formik.status && (
<p className={'error-message'}>{formik.status}</p>
)
}
</div>
</div>
{/* end::Heading */}
{/* begin::Form group content */}
<div className={'auth-form-content'}>
{/* begin::Form group */}
<div className={'dynamic-input-container'}>
<input type='text'
id="username"
value={formik.values.username}
onChange={formik.handleChange}
placeholder='Username'
className={'dynamic-input auth-input ' + clsx(
{'is-invalid': formik.touched.username && formik.errors.username},
{
'is-valid': formik.touched.username && !formik.errors.username
}
)}
autoComplete='off'
/>
{formik.touched.username && formik.errors.username && (
<div className='fv-plugins-message-container'>
<span role='alert'>{formik.errors.username}</span>
</div>
)}
</div>
{/* end::Form group*/}
{/* begin::Action */}
<div className='auth-btn-container'>
<Button variant="contained" size="medium" type={'submit'} disabled={loading}>
{
!loading ? <span>Continue</span>
:
(
<span className={'auth-spinner-container'}>
<ClipLoader
loading={loading}
size={20}
aria-label='Loading Spinner'
/>
</span>
)
}
</Button>
</div>
{/* end::Action */}
</div>
{/* end::Form group content */}
</form>
);
Please note, that in my example I only have a "username" input, but you can obviously add as many fields as you wish.
Documentation:
Formik: https://formik.org/docs/tutorial
Yup: https://www.npmjs.com/package/yup
clxs: https://www.npmjs.com/package/clsx
import React, { useState } from 'react';
import { Button, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useNavigate } from 'react-router';
export default function Create() {
let navigate = useNavigate();
const [Employee_name, setEmployee_name] = useState('');
const [Employee_id, setEmployee_id] = useState('');
const [Employee_address, setEmployee_address] = useState('');
const [Employee_post, setEmployee_post] = useState('');
const postData = e => {
e.preventDefault();
if(Employee_name.length == 0) return false;
if(Employee_id.length == 0) return false;
if(Employee_address.length == 0) return false;
if(Employee_post.length == 0) return false;
axios.post(`http://localhost:5000/qo`, {
Employee_name,
Employee_id,
Employee_address,
Employee_post
}).then(() => {
navigate('/read')
})
alert('Data Saved')
}
return (
<div>
<Form className="create-form" onSubmit={e => postData(e)}>
<Form.Field required={true}>
<label>Employee Name</label>
<input placeholder='Employee Name' onChange={(e) => setEmployee_name(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee ID</label>
<input placeholder='Employee ID' onChange={(e) => setEmployee_id(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Address</label>
<input placeholder='Employee Address' onChange={(e) => setEmployee_address(e.target.value)} required={true}/>
</Form.Field>
<Form.Field required={true}>
<label>Employee Position</label>
<input placeholder='Employee Position' onChange={(e) => setEmployee_post(e.target.value)} required={true}/>
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
</div>
)
}
This is updated code from your snippet. try this and let me know what's the progress.
I really appreciate you.

I want to reset my form after clicking submit in reactjs. I have tried making another method. but it does not work

import React,{ useState} from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react';
import axios from 'axios';
const Create = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
Here I am sending data to a mock api I created
const postData = () =>{
axios.post(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData`,{
firstName,
lastName,
checkbox
})
}
This is the method I created to reset the form but it does not work.
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
}
This is my form where on click i am calling resetForm function but it is not resetting it
is sending the data but not resetting the form.
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder='First Name' onChange={(e)=>setFirstName(e.target.value) } />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder='Last Name' onChange={(e)=>setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox id="c1" label='I agree to the Terms and Conditions' onChange={(e)=>setCheckBox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={resetForm}>Submit</Button>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Create;
Actually it will reset the form, the problem is you do not use Controlled Components to show the latest update value in UI
you should bind the value like this:
<input type="text" value={this.state.value} onChange={this.handleChange} />
You can refer the doc here:
https://reactjs.org/docs/forms.html
You can reset your form using the native form.reset() method.
const Create = () => {
const ref = React.useRef(null);
const resetForm = () => ref.current.reset();
return (
<div>
<Form ref={ref}>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder="First Name" onChange={(e) => setFirstName(e.target.value)} />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder="Last Name" onChange={(e) => setLastName(e.target.value)} />
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
<br></br>
<Button onClick={() => navigate(-1)}>Go Back</Button>
</div>
);
};
export default Create;
For that, you have to set value property in your input. Try this
const Create = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [checkbox, setCheckBox] = useState(false);
const postData = () => {
console.log(firstName, lastName, checkbox);
};
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
};
return (
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input
id="f1"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input
id="last1"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
checked={checkbox}
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
</div>
);
};

I want to redirect to a new page on react on a conditon

Error:Line 33:13: Expected an assignment or function call and instead saw an expression no-unused-expressions
I used the Route and Browser Router to create the link to the page.
I need to redirect to the home page on signing in.
import axios from 'axios'
import {Redirect} from 'react-router-dom'
import React,{Component} from 'react'
const url ="http://localhost:80/phpfile"
class Signup extends Component{
constructor(){
super();
this.state={
username:"",
password:"",
value:false
}
}
sign=e=>{
e.preventDefault();
const user={
"username":this.state.username,
"password":this.state.password
}
axios.post(url,user,{"header":{ "content-type": "application/json",}}
)
.then(result=>{if (result.data===true)
{
this.setState({value:true});
}
})
if(this.state.value){
<Redirect to='/'/>
}
}
render(){
const value= this.state.value;
return(
<div>
<form action="#">
<label> Username</label>
<input name="name" value="Enter the usrname" id ="name"
onChange={e => this.setState({ username: e.target.value })}/>
<label>Password</label>
<input type="password" placeholder="Enter Password" id="pass"
name="pass" onChange={e => this.setState({password: e.target.value })}/>
<botton onClick={e=>this.sign(e)}>Signin</botton>
</form>
</div>
)
}
}
export default Signup;
As you are not using state anywhere, you can add redirect instead of setting state:
...
.then(result=>{if (result.data===true)
{
return <Redirect to='/'/>
}
})
or if state requirement is there, then based on state you can add the Redirect in return statement of component
render(){
const value= this.state.value;
return(
<div>
{!value ?
(<form action="#">
<label> Username</label>
<input name="name" value="Enter the usrname" id ="name"
onChange={e => this.setState({ username: e.target.value })}/>
<label>Password</label>
<input type="password" placeholder="Enter Password" id="pass"
name="pass" onChange={e => this.setState({password: e.target.value })}/>
<botton onClick={e=>this.sign(e)}>Signin</botton>
</form>)
: (<Redirect to='/'/>)
}
</div>
)
}

where to put my header and footer tags in reactjs

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { login } from '../../redux/reducer';
import './LoginForm.css';
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {};
this.onSubmit = this.onSubmit.bind(this);
}
render() {
let {username, password} = this.state;
let {isLoginPending, isLoginSuccess, loginError} = this.props;
return (
<header>
<h1>Company Login</h1>
</header>
<form name="loginForm" onSubmit={this.onSubmit}>
<div className="form-group-collection">
<div className="form-group">
<label>Username/User ID:</label>
<input name="username" onChange={e => this.setState({username: e.target.value})} value={username}/>
</div>
<div className="form-group">
<label>Password:</label>
<input type="password" name="password" onChange={e => this.setState({password: e.target.value})} value={password}/>
</div>
</div>
<br/>
<input type="submit" value="Login" />
</form>
<footer>Copyright © multihands.com. </footer>
)
}
onSubmit(e) {
e.preventDefault();
let { username, password } = this.state;
this.props.login(username, password);
this.setState({
username: '',
password: ''
});
}
}
const mapStateToProps = (state) => {
return {
isLoginPending: state.isLoginPending,
isLoginSuccess: state.isLoginSuccess,
loginError: state.loginError
};
}
const mapDispatchToProps = (dispatch) => {
return {
login: (username, password) => dispatch(login(username, password))
};
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
This is my login page i want to add header in my page.. I added it already as shown in the code...But unfortunetly error occurs after running.. Where does I put my header and footer tag in my code.. If we put it in form the code runs..But the css applied to the form is affected by adding the footer and header.. So I need the correct way to place header and footer without intrude my form..
Issue is that return statement must contain a single element only and your code contains three. So basically this should work:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { login } from '../../redux/reducer';
import './LoginForm.css';
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {};
this.onSubmit = this.onSubmit.bind(this);
}
render() {
let { username, password } = this.state;
let { isLoginPending, isLoginSuccess, loginError } = this.props;
return (
<div>
<header>
<h1>Company Login</h1>
</header>
<form name="loginForm" onSubmit={this.onSubmit}>
<div className="form-group-collection">
<div className="form-group">
<label>Username/User ID:</label>
<input name="username" onChange={e => this.setState({ username: e.target.value })} value={username} />
</div>
<div className="form-group">
<label>Password:</label>
<input type="password" name="password" onChange={e => this.setState({ password: e.target.value })} value={password} />
</div>
</div>
<br />
<input type="submit" value="Login" />
</form>
<footer>Copyright © multihands.com. </footer>
</div>
)
}
onSubmit(e) {
e.preventDefault();
let { username, password } = this.state;
this.props.login(username, password);
this.setState({
username: '',
password: ''
});
}
}
const mapStateToProps = (state) => {
return {
isLoginPending: state.isLoginPending,
isLoginSuccess: state.isLoginSuccess,
loginError: state.loginError
};
}
const mapDispatchToProps = (dispatch) => {
return {
login: (username, password) => dispatch(login(username, password))
};
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
You need a wrapper inside your render function this solution should reolve your issue:-
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { login } from '../../redux/reducer';
import './LoginForm.css';
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {};
this.onSubmit = this.onSubmit.bind(this);
}
render() {
let { username, password } = this.state;
let { isLoginPending, isLoginSuccess, loginError } = this.props;
return (
<div className="wrapper">
<header>
<h1>Company Login</h1>
</header>
<form name="loginForm" onSubmit={this.onSubmit}>
<div className="form-group-collection">
<div className="form-group">
<label>Username/User ID:</label>
<input name="username" onChange={e => this.setState({ username: e.target.value })} value={username} />
</div>
<div className="form-group">
<label>Password:</label>
<input type="password" name="password" onChange={e => this.setState({ password: e.target.value })} value={password} />
</div>
</div>
<br />
<input type="submit" value="Login" />
</form>
<footer>Copyright © multihands.com. </footer>
</div>
);
onSubmit(e) {
e.preventDefault();
let { username, password } = this.state;
this.props.login(username, password);
this.setState({
username: '',
password: ''
});
}
}
}
const mapStateToProps = (state) => {
return {
isLoginPending: state.isLoginPending,
isLoginSuccess: state.isLoginSuccess,
loginError: state.loginError
};
}
const mapDispatchToProps = (dispatch) => {
return {
login: (username, password) => dispatch(login(username, password))
};
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
If you don't need the wrapper div you can use the Fragments(https://reactjs.org/docs/fragments.html) if using React Fiber.
<React.Fragment>
<header>
<h1>Company Login</h1>
</header>
<form name="loginForm" onSubmit={this.onSubmit}>
<div className="form-group-collection">
<div className="form-group">
<label>Username/User ID:</label>
<input name="username" onChange={e => this.setState({ username: e.target.value })} value={username} />
</div>
<div className="form-group">
<label>Password:</label>
<input type="password" name="password" onChange={e => this.setState({ password: e.target.value })} value={password} />
</div>
</div>
<br />
<input type="submit" value="Login" />
</form>
<footer>Copyright © multihands.com. </footer>
</React.Fragment>

Categories

Resources