I am working on a project where if the login detail is valid, we move to the next page ("/home"). But in my case, while it works perfectly good when the email is invalid, it does not go the expected page when the email is valid. Instead, the page only reloads. Although I have done the necessary in the onSubmit function. Please help
class Test extends React.Component {
constructor(){
super();
this.state = emailState;
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
email : e.target.value
});
}
emailValidation(){
const regex = /^(([^<>()[\]\.,;:\s#\"]+(\.[^<>()[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()[\]\.,;:\s#\"]+\.)+[^<>()[\]\.,;:\s#\"]{2,})$/i;
if(!this.state.email || regex.test(this.state.email) === false){
this.setState({
error: "Email is not valid"
});
return false;
}
return true;
}
onSubmit(){
if(this.emailValidation()){
console.log(this.state);
this.props.history.push('/home');
}
}
render(){
return (
<div className="login-cot bg-danger" id="layoutAuthentication">
<div id="layoutAuthentication_content">
<main>
<div className="container ">
<div className="row justify-content-center ">
<div className="col-lg-5 ">
<div className="card shadow-lg border-0 rounded-lg mt-5 bg-secondary">
<center><h1 className="bg-warning" style={{padding:"10px",}}><b><BsBugFill /><BsTools /> <BsColumns /> BFP</b></h1></center>
<div className="card-header"><h3 className="text-center my-1"><b>Login</b></h3></div>
<div className="card-body">
<form>
<div className="form-floating mb-3">
<input className="form-control" id="email" type="email"
placeholder="name#example.com"
value={this.state.email}
onChange={this.onChange}
/>
<label for="inputEmail">Email address</label>
<span className="text-danger">{this.state.error}</span>
</div>
<button type ="submit" className="btn btn-success" onClick={()=>this.onSubmit()}>Login</button>
</form>
</div>
<div className="card-footer text-center py-3">
<div className="small"><Link className="text-light" to="/signup">Need an account? Sign up!</Link></div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
)
}
}
Try to use withRouter() function with react , which helps to access the history parameter.
For e.g in your case : export default withRouter(Test);
Related
I am working with simple form validation in react. The problem here is error message is not displaying in while it is showing in console.log! I am quite new to react and stucked here for quite some time. How can I solve this?
I've seen many youtube videos but nothing is working properly.
const [logindata, setLogindata] = useState({
customeremail: '',
customerpass: ''
})
const [err, seterr] = useState({
Email: '',
Passwordnew: ''
});
const handlechange = event => {
const val = event.target.value
const name = event.target.name
setLogindata({ ...logindata, [name]: val })
console.log(val)
}
function login() {
const NewErr = {...err};
if (logindata.customeremail == "") {
NewErr.Email = "Email should not be empty";
alert(NewErr.Email)
console.log(NewErr)
}
}
return (
<>
<div className="container">
<div className="row">
<div className="col-12 col-sm-12 col-md-6 col-lg-6 main-col offset-md-3">
<div className="mb-4">
<form method="post" action="home" id="CustomerLoginForm" acceptCharset="UTF-8" className="contact-form">
<div className="row">
<div className="col-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<label htmlFor="CustomerEmail">Email</label>
<input type="email" name="customeremail" placeholder="" id="CustomerEmail" className="" autoCorrect="off" autoCapitalize="off" autoFocus="" onChange={handlechange} value={logindata.customeremail} required = {true} />
</div>
<div className="alert alert-danger" role="alert">
{seterr.Email}
</div>
</div>
<div className="col-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<label htmlFor="CustomerPassword">Password</label>
<input type="password" name="customerpass" placeholder="" id="CustomerPassword" className="" onChange={handlechange} value={logindata.customerpass} />
</div>
</div>
</div>
<div className="row">
<div className="text-center col-12 col-sm-12 col-md-12 col-lg-12">
<input type="button" style={{ backgroundColor: '#000', color: '#fff' }} className="btn mb-3" value="Sign In" onClick={login} />
<p className="mb-4">
Forgot your password? |
Create account
</p>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</>
There are 2 problem in your code
1. Not setting state
You are not setting state for err using seterr as:
if (logindata.customeremail == '') {
NewErr.Email = 'Email should not be empty';
alert(NewErr.Email);
console.log(NewErr);
seterr(NewErr); // MISSING
}
CODESANDBOX LINK
2. Showing error message with wrong way
When you use useState then it will give you an array of value and function through which you can update the value and on change of the value it will re-render it. You have to use err obj not the function seterr.
You should use {err.Email}} instead of {seterr.Email}}
<div className='alert alert-danger' role='alert'>
{/* {seterr.Email} */}
{err.Email}
</div>;
I am trying to add a spinner but there is a problem while executing the program
import React,{Component} from 'react';
import axios from 'axios';
import LoginFailModal from './LoginFailModal';
class Login extends Component
{
constructor(props)
{
super(props);
this.state = {
username : "",
password : "",
error:false,
loading:false
}
}
inputSet =(e)=> {
//console.log(e.target.name);
this.setState({[e.target.name]:e.target.value})
}
loginCheck =(e)=>{
this.setState({['error']:false});
this.setState({['loading']:true});
e.preventDefault();
var data = {
emph : this.state.username,
password : this.state.password
};
axios.post("url",data).then(response=>{
if(response.data.status=='200')
{
var response_data = response.data.data;
var user_data = {'token':response_data.token,
'user_type':'staf'}
localStorage.setItem('user_data', user_data);
this.setState({['error']:true,['loading']:false});
}
else
{
this.setState({['error']:true,['loading']:false});
}
})
}
render()
{
let {loading} = this.state;
return(
<>
{this.state.error ? (<LoginFailModal/>):""}
<div class="row">
<div className="col-xl-7 col-lg-4 col-md-2">
<img className="bg_img" src="assets/images/bg.jpg" alt=""/>
</div>
<div className="col-xl-5 col-lg-4 col-md-2">
<div className="login">
<img className="login-logo" src="assets/images/login-logo.png" alt=""/>
<form className="input">
<input className="text-field" type="text" name="username" onChange={this.inputSet} placeholder="Username" id=""/>
<input className="text-field" type="password" name="password" onChange={this.inputSet} placeholder="Password" id=""/>
<p className="fp">Forgot Password?</p>
<div className="cal">
<div className="row">
<div col-xl-4 col-lg-2 col-md-2>
<p className="sum">40+40</p>
</div>
<div col-xl-5 col-lg-2 col-md-2>
<input className="get" type="text" name="" placeholder="" id=""/>
</div>
</div>
</div>
<div className="row">
<p className="pl-5 remember"><input type="checkbox" name="remember me" id=""/>
Remember me</p>
</div>
<div className="login_button">
<p style={{color: "red"}}>{this.state.error}</p>
<button className="button" onClick={this.loginCheck}>Login
{loading && <i className="fa fa-refresh fa-spin" style={{color:'white'}}></i>}</button>
</div>
</form>
</div>
</div>
</div>
</>
)
}
}
export default Login;
Hitting submit from http://localhost:3000/newReport.
i have three fields treeselectdropdown, a textbox and a number field. i am setting days in state.
It redirect to http://localhost:3000/newReport?days=10 (if i give no of days as 10).
**import React from 'react';
import TestDropdownTreeSelect from './DropdownTreeSelect';
import Select from 'react-select';
class NewReport extends React.Component{
constructor() {
super();
this.state = {
days:null
};
this.getResults = this.getResults.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange({ target }) {
this.setState({
days: target.value
});
}
getResults() {
if(this.state.days!=null || this.state.days!=0)
alert(this.state.days);
fetch('*********************/************/getReportData?libraryName=R1_CONTENT_en_IN')
.then(res => res.text())
.then(text => {
console.log('R4_CONTENT_en_US----------------')
console.log(text);
console.log('R4_CONTENT_en_US----------------')
}).catch(err => {
console.log("ERROR: " + err);
})
}
render(){
return (
<div>
<form required>
<div class="label">
<b>New Report</b>
</div>
<br></br>
<div className="container">
<div class="row">
<div class="col-md-2">
<div class="labelNameLib">
<b>Library</b>
</div></div>
<div class="col-md-4">
<TestDropdownTreeSelect />
</div>
</div>
</div>
<div className="container">
<div className="row">
<div className="col-md-2">
<div class="labelName">
<b>Author</b>
</div>
</div>
<div className="col-md-2">
{/* <Select options={Authors}></Select> */}
<input type="text" ></input>
</div>
<div className="col-md-2"></div>
</div>
</div>
<br></br>
<div className="container">
<div className="row">
<div className="col-md-2">
<div class="labelName">
<b>Expiry Date in Next</b>
</div> </div>
<div className="col-md-2">
<input type="number" required
title="Enter number from 1 to 365"
value={ this.state.days } name="days"
onChange={ this.handleChange }
pattern="[0-9]{1,3}" min="1" max ="365"></input>
</div>
<div className="col-md-1"><b>Days</b></div>
</div>
</div>
<br></br>
<div>
<button type="submit" class="runReport"
onClick={this.getResults}
style={{ backgroundColor: '#FFD700', marginLeft: '15%' }}>Run Report</button>
</div>
<div>
</div>
</form>
</div>
);
}
}**
I am not getting rest api result in console. Why it is redirecting to ?days=10.
i am using fetch for hitting rest api requests
This is the expected behaviour with a form. You test the example on the page, the page is reloaded. To prevent this with JavaScript you have to use event.preventDefault(). Here is the snippet updated:
class NewReport extends React.Component{
getResults(event) {
event.preventDefault();
// ...
}
}
I want to send that state of a component to the actions file.
My component is a <form> where the user can capture some config that later i want to apply that config to the actions file.
Component Code:
import React, { Component } from 'react';
class AdminConfig extends Component{
constructor(props){
super(props);
this.state=({
baseURL:'BASE_URL',
hospitalName: '',
hospitalExternalID:'1000849',
payerName:'',
payerAddress:''
})
this.onBaseURLChange = this.onBaseURLChange.bind(this);
this.onHospitalNameChange = this.onHospitalNameChange.bind(this);
this.onHospitalExIDChange = this.onHospitalExIDChange.bind(this);
this.onPayerNameChange = this.onPayerNameChange.bind(this);
this.onPayerAddressChange = this.onPayerAddressChange.bind(this);
this.onAdminFormSubmit = this.onAdminFormSubmit.bind(this);
}
onBaseURLChange(e){
this.setState({
baseURL: e.target.value
})
}
onHospitalNameChange(e){
this.setState({
hospitalName: e.target.value
})
}
onHospitalExIDChange(e){
}
onPayerNameChange(e){
this.setState({
payerName: e.target.value
})
}
onPayerAddressChange(e){
this.setState({
payerAddress: e.target.value
})
}
onAdminFormSubmit(e){
e.preventDefault()
// here is where i need to send something like this:
this.props.fetchAdminConfig(this.state.baseURL)
}
render(){
return(
<div className="container ">
<form className="admin-form" onSubmit={this.onAdminFormSubmit}>
<div className="row">
<div className="jumbotron col-md-12">
<h4>API CONFIGURATION</h4>
</div>
<div className="col-md-12">
<div className="panel panel-primary">
<div className="panel-heading">BASE URL</div>
<div className="panel-body">
<input
onChange={this.onBaseURLChange}
type="text"
className="form-control"
id="baseURL"
placeholder="Base URL" />
<div className="panel-body" id="getResult"> <p className="">Base URL: http://{this.state.baseURL}/trucare-api-6.2.1.TC621/6.2.1/api</p></div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="jumbotron col-md-12">
<h4>HOSPITAL INFORMATION</h4>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Hospital Name</div>
<div className="panel-body">
<input
onChange={this.onHospitalNameChange}
type="text"
className="form-control"
id="hospitalName"
placeholder="Hospital Name" />
<div className="panel-body" id="getResult"><p className="">Hospital name: {this.state.hospitalName}</p></div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Hospital External ID</div>
<div className="panel-body">
<input
onChange={this.onHospitalExIDChange}
type="text"
className="form-control"
id="hospitalEXID"
placeholder="Hospital Name" disabled />
<div className="panel-body" id="getResult"><p>Hospital External ID: {this.state.hospitalExternalID}</p></div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="jumbotron col-md-12">
<h4>PAYER INFORMATION</h4>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Name</div>
<div className="panel-body">
<input
onChange={this.onPayerNameChange}
type="text"
className="form-control"
id="payerName"
placeholder="Payer Name" />
<div className="panel-body" id="getResult"><p>Payer Name: {this.state.payerName}</p></div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Address</div>
<div className="panel-body">
<input
onChange={this.onPayerAddressChange}
type="text"
className="form-control"
id="payerAddress"
placeholder="Payer Address" />
<div className="panel-body" id="getResult"><p>Payer Address: {this.state.payerAddress}</p></div>
</div>
</div>
</div>
</div>
<button type="submit" className="btn btn-primary btn-lg">Apply config</button>
</form>
</div>
);
}
}
export default AdminConfig
Then on my actions file I have this:
export function fetchAdminConfig(BASE_URL){
...
}
const BASE_URL = //this is where I want to apply the state that I captued on my form
export function fetchUsers() {
const request = axios.post(`${BASE_URL}/endpoint`)
return {
type: FETCH_USERS,
payload: request
};
}
How Can I accomplish this?
Just add a parameter to your action creator function and pass it in!
export function fetchAdminConfig(BASE_URL) {
const request = axios.post(`${BASE_URL}/endpoint`)
return {
type: FETCH_USERS,
payload: request
};
}
how can I use redux so that my values of my form get accesible to other components.Currently I've this:
import React, { Component } from 'react';
class AdminConfig extends Component{
constructor(props){
super(props);
this.state=({
payerName:'',
payerAddress:''
})
this.onPayerNameChange = this.onPayerNameChange.bind(this);
this.onPayerAddressChange = this.onPayerAddressChange.bind(this);
this.onAdminFormSubmit = this.onAdminFormSubmit.bind(this);
}
onPayerNameChange(e){
this.setState({
payerName: e.target.value
})
}
onPayerAddressChange(e){
this.setState({
payerAddress: e.target.value
})
}
onAdminFormSubmit(e){
e.preventDefault()
// I guess here goes the magic
}
render(){
return(
<div className="container ">
<form className="admin-form" onSubmit={this.onAdminFormSubmit}>
<div className="row">
<div className="jumbotron col-md-12">
<h4>PAYER INFORMATION</h4>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Name</div>
<div className="panel-body">
<input
onChange={this.onPayerNameChange}
type="text"
className="form-control"
id="payerName"
placeholder="Payer Name" />
<div className="panel-body" id="getResult"><p>Payer Name: {this.state.payerName}</p></div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Address</div>
<div className="panel-body">
<input
onChange={this.onPayerAddressChange}
type="text"
className="form-control"
id="payerAddress"
placeholder="Payer Address" />
<div className="panel-body" id="getResult"><p>Payer Address: {this.state.payerAddress}</p></div>
</div>
</div>
</div>
</div>
<button type="submit" className="btn btn-primary btn-lg">Apply config</button>
</form>
</div>
);
}
}
export default AdminConfig
Im using a boilerplate called redux simple starter from Stephen Grider and there is a directory for actions and reducers. Whats next in order to apply redux to my form ?