Why onSubmit is not working with React ES6 syntax? - javascript

I am a newbie in React world. Actually, I come across a situation. When I use modern syntax, I am not getting things done. But, with bind.this method everything is working smoothly. Below is my code. Can you please find out mistakes. It giver error like "cant find state of undefined". Thank you.
import React, { Component } from 'react';
class Login extends Component {
state = {
email: '',
password: '',
}
handleChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
signin(e) {
e.preventDefault();
const { email, password } = this.state;
if (email === 'xyz#gmail.com' && password === '123456') {
console.log('logged in')
}
}
render() {
return(
<div className='login'>
<div className='login-div'>
<form
onSubmit={this.signin}>
<fieldset>
<h2 className='heading'>Sign into your account</h2>
<label htmlFor="email">
<input
type="email"
name="email"
placeholder="email"
value={this.state.email}
onChange={this.handleChange}
/>
</label>
<label htmlFor="password">
<input
type="password"
name="password"
placeholder="password"
value={this.state.password}
onChange={this.handleChange}
/>
</label>
<button type="submit">Sign In!</button>
</fieldset>
</form>
</div>
</div>
)
}
}
export default Login;

can you change your function to this
signin = (e) => {
e.preventDefault();
const { email, password } = this.state;
if (email === 'xyz#gmail.com' && password === '123456') {
console.log('logged in')
}
}

Just to explain what's going on :
It's because inside signin function, this refers to the context of the execution (the event handler) but not to your React component.
You can specify which this the signin function will be bound to using bind method.
Add this line at the begining of the class :
this.signin = this.signin.bind(this);
Note : You can avoid binding all your functions by writing them using arrow function syntax.

Related

this.props.history.push('/') IS NOT WORKING in CLASS Component

Please help me to resolve the issue of this.props.history.push('/') IS NOT WORKING in CLASS Component. As we do not have any scope of using history anymore. Unable to implement navigate.
Please do help. Same issue with props.location.state.contact.
**const { name, email } = props.location.state.contact;**
import React, { Component } from "react";
import "../assets/css/AddContact.css";
import { Navigate } from "react-router-dom";
import { v4 as uuid } from "uuid";
class AddContact extends Component {
state = {
id: uuid(),
name: "",
email: "",
};
add = (e) => {
e.preventDefault();
if (this.state.name === "" || this.state.email === "") {
alert("All fields are required!");
return;
}
this.props.addContactHandler(this.state);
this.setState({ name: "", email: "" });
this.props.history.push("/");
};
render() {
return (
<div className="contactForm">
<h2 className="contactForm__title">Add Contact</h2>
<div className="contactForm__form">
<form action="/" method="post" onSubmit={this.add}>
<div className="contactForm__nameField">
<label htmlFor="name">Name</label>
<br />
<input
type="text"
placeholder="Enter your name"
name="name"
id="name"
value={this.state.name}
onChange={(e) => this.setState({ name: e.target.value })}
/>
</div>
<div className="contactForm__emailField">
<label htmlFor="email">Email</label>
<br />
<input
type="email"
placeholder="Enter your email"
name="email"
id="email"
value={this.state.email}
onChange={(e) => this.setState({ email: e.target.value })}
/>
</div>
<button className="contactForm__button">Add</button>
</form>
</div>
</div>
);
}
}
export default AddContact;
I tried out from all of my references.
You need to use the withRouter Higher Order Component provided with the React Router library in order to get access to those props (history and location automatically).
So just import that, and change your export to
export default withRouter(AddContact);
[Note that this assumes you are using React Router v5 or before - there is no withRouter in v6 which is the latest version. But your use of a class component implies that you are using an earlier version - v6 only works well if you use function components, as withRouter has been replaced with Hooks.]

why did not worked validation in react component

problem image is here-->
https://postimg.cc/4mYB30C6
There are two problems
One: warning me the controlled component to uncontrol though I use handler event;
Second: js include function 1st time define 2nd-time type error.
I cannot find my problem I use two-time value and define it with let but they told im not to define 2nd why include showing me type error
import React,{useState} from 'react'
//component
export default function Form() {
const [allValues,setAll] = useState({
name:"",
email:"",
pass:"",
nameerr:"",
passerr:"",
emailerr:"",
});
//valide function
let valide= ()=>{
let nameerr;
let passerr;
let emailerr;
if(!allValues.name)
{
nameerr='your name invalid';
}
if(!allValues.email.includes('#'))
{
emailerr='your Email invalid';
}
if(!allValues.pass.match(1))
{
passerr='your pass invalid';
}
if(nameerr||emailerr||passerr)
{
let newValue={nameerr,emailerr,passerr};
setAll(newValue);
return false;
}
return true;
}
//Onchange handaler
const handalChange=(e)=>{
setAll({...allValues,[e.target.name]:e.target.value});
}
//Onsubmit handaler
const handalSubmit=(e)=>{
e.preventDefault();
const NewValide=valide();
if(NewValide!==false){
let value={...allValues,
nameerr:"",
passerr:"",
emailerr:"",}
setAll(value);
console.log(value)
}
else{
valide();
}
}
return (
<form onSubmit={handalSubmit} >
<div>
Name: <input
placeholder="name"
type="text"
name="name"
value={allValues.name}
onChange={handalChange}
/>
<div>{allValues.nameerr}</div>
<div>
Email: <input
placeholder="email"
type="text"
name="email"
onChange={handalChange}
value={allValues.email}
/>
</div>
<div>{allValues.emailerr}</div>
<div>
password: <input
placeholder="password"
type="password"
name="pass"
onChange={handalChange}
value={allValues.pass}
/>
</div>
<div>{allValues.passerr}</div>
</div>
<input type="submit" value="Submit"/>
</form >
)
}
You are using wrong syntax when you are calling setAll() in valide fuction.
Try to call
setAll({... allValues, nameerr:nameerr ,emailerr: emailerr,passerr: passerr})
By doing this you will have access to other properties of allValues

How to integrate react-intl-tel-input

Hello I am new in ReactJS and I have to implement react-intl-tel-input for taking phone number from all over the world but while integration I was facing some issues. When I write this code:
<IntlTelInput
containerClassName="intl-tel-input"
inputClassName="form-control"
name="mobile"
placeholder="Enter Your Number"
input
type="tel"
value={this.state.phoneNumber}
onChange={this.handleChange}
I was not able to access this.handleChange but When I write my normal code like this
<input
type="tel"
id="phone"
name="mobile"
placeholder="Enter Your Number"
required
onChange={this.handleChange}
/>
I was able to access this.handleChange and my code work perfectly but I was unable to take country code. If anyone know the solution please help. I was getting this error
TypeError: Cannot read properties of null (reading 'phoneNumber')
This is my complete code.
Login.js
import React from 'react'
import firebase from './firebase'
import 'firebase/auth';
import "./App.css";
import { getDatabase, ref, child, get } from "firebase/database";
import IntlTelInput from 'react-intl-tel-input';
import 'react-intl-tel-input/dist/main.css';
class Login extends React.Component {
handleChange = (e) => {
console.log (e)
const { name, value } = e.target
this.setState({
[name]: value
})
console.log (value)
this.setState({ phoneNumber: value }, () => {
console.log(this.state.phoneNumber);
});
}
configureCaptcha = () =>{
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
this.onSignInSubmit();
console.log("Recaptca varified")
},
// defaultCountry: "IN"
}
);
}
onSignInSubmit = (e) => {
e.preventDefault()
this.configureCaptcha()
const phoneNumber = this.state.mobile
console.log(phoneNumber)
const appVerifier = window.recaptchaVerifier;
const dbRef = ref(getDatabase());
get(child(dbRef, `Users/${phoneNumber}`)).then((snapshot) => {
if (snapshot.exists()) {
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
.then((confirmationResult) => {
window.confirmationResult = confirmationResult;
alert('An OTP has been sent to your registered mobile number')
localStorage.setItem("Phone_No", phoneNumber)
console.log(localStorage.getItem('Phone_No'));
}).catch((error) => {
console.error(error);
alert("Oops! Some error occured. Please try again.")
});
}
else {
alert('Sorry, this mobile number is not registered with us. Please use your registered mobile number.');
}
})
}
onSubmitOTP = (e) => {
e.preventDefault()
const code = this.state.otp
console.log(code)
window.confirmationResult.confirm(code).then((result) => {
// User signed in successfully.
const Users = result.user;
console.log(JSON.stringify(Users))
this.props.history.push("/home");
}).catch((error) => {
alert("You have entered wrong code")
});
}
render() {
return (
<div className="Main-header">
<img src="./55k-logo.png" alt="Company Logo" style={{ height: "80px", width: "200px" }} />
<br />
<div>
<h2>Login Form</h2>
<p>Limtless Water. From Unlimited Air.</p>
<form onSubmit={this.onSignInSubmit}>
<div id="sign-in-button"></div>
{/* <PhoneInput */}
<label>Mobile Number</label> <br />
{/* for="phoneNumber" */}
<IntlTelInput
containerClassName="intl-tel-input"
inputClassName="form-control"
name="mobile" placeholder="Enter Your Number"
input type="tel" value={this.state.phoneNumber}
onChange={this.handleChange}
/>
{/* <input type="tel" id="phone" name="mobile" placeholder="Enter Your Number" required onChange={this.handleChange} /> */}
<div className="buttons">
<button type="submit">Submit</button>
</div>
</form>
</div>
<div>
<form onSubmit={this.onSubmitOTP}>
<label >Code</label> <br />
{/* for="code" */}
<input type="number" name="otp" placeholder="Enter The 6 Digit OTP" required onChange={this.handleChange} />
<div className="buttons" >
<button type="submit">Submit</button>
</div>
</form>
</div>
</div>
)
}
}
export default Login;
Issues
There is no defined initial state so this is why accessing this.state.phoneNumber is throwing an error.
The IntlTelInput component takes an onPhoneNumberChange handler that takes a validation status, current value, and country details as arguments instead of an onChange handler taking an onChange event object.
Solution
Provide valid initial state for the component. In React class components state is simply a class property, it just needs to be defined.
state = {};
Create a new change handler specifically for the IntlTelInput component.
handlePhoneChange = (status, phoneNumber, country) => {
this.setState({ phoneNumber });
};
Switch from onChange to onPhoneNumberChange event handler.
<IntlTelInput
containerClassName="intl-tel-input"
inputClassName="form-control"
name="mobile"
placeholder="Enter Your Number"
input
type="tel"
value={this.state.phoneNumber}
onPhoneNumberChange={this.handlePhoneChange}
/>

Problem with input values in React (A component is changing a controlled input of type password to be uncontrolled.)

I am trying to set up sign up page using React. I am passing values from state to "sign up" component through props. When I type password and try to submit it two things happen:
the predefined alert saying that password and confirmed password do not match pops up
the error saying "A component is changing a controlled input of type password to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component." occurs
p.s. I tried using Short-circuit evaluation (ex. value={this.state.fields.name || ''} ) but the input values keep refreshing to empty value. In my project I am using firebase.
class App extends Component {
state = {signUpPage: {
displayName: '',
email: '',
password: '',
confirmPassword: ''
}
signUpHandleChange = (event) => {
const {name, value} = event.target
this.setState({
signUpPage: {
[name]: value
}
})
}
handleSubmitSignUp = async event => {
event.preventDefault();
const { displayName, email, password, confirmPassword} = this.state.signUpPage
if (password !== confirmPassword) {
alert("passwords do not match")
return
}
try{
const {user} = await auth.createUserWithEmailAndPassword(email, password);
await createUserProfileDocument(user, {displayName});
this.setState({
signUpPage: {
displayName: '',
email: '',
password: '',
confirmPassword: ''
}
})
} catch (error) {
console.error(error)
}
}
render(){
return (
<BrowserRouter>
<div>
<SigningPage
signUpEmail={this.state.signUpPage.email}
signUpPassword={this.state.signUpPage.password}
signUpConfirmPassword={this.state.signUpPage.confirmPassword}
signUpValueChange={this.signUpHandleChange}
signUpsubmit={this.handleSubmitSignUp}/>
</div>
</BrowserRouter>
);
} }
//this is the SigningPage component
const SigningPage = (props) => {
return <article className={`${classes.signingpageitems} ${classes.signuppage}`}>
<h1 >Sign up</h1>
<form onSubmit={props.signUpsubmit}>
<input
name="email"
type="email"
value={props.signUpEmail}
className={classes.signingpageitem}
onChange={props.signUpValueChange}
placeholder="email"
required>
</input>
<input
name="password"
type="password"
value={props.signUpPassword}
className={classes.signingpageitem}
onChange={props.signUpValueChange}
placeholder="password"
required>
</input>
<input
name="confirmPassword"
type="password"
value={props.signUpConfirmPassword}
className={classes.signingpageitem}
onChange={props.signUpValueChange}
placeholder="confirm password"
required>
</input>
<input type="submit" value="Submit form" className={`${classes.signingpageitem} ${classes.signbtn}`}>
</input>
</form>
</article>
}
I solved the issue. The "name" atrribute did not match "value" attribute in the inputs.

Unable to type into React input field

I am unable to type any input into my input field. I am using React, and have already set a handleChange and a handleSubmit function. The first two input fields, for 'name' and 'email', take input just fine. But for 'favoriteCity', it doesn't seem to work.
I am wondering if it is due to a MongoDB error that I am getting.
class UserPage extends Component {
state = {
user: [],
newUser: {
name: '',
email: '',
favoriteCity: ''
}
}
getAllUsers = () => {
axios.get('/api/users')
.then(res => {
this.setState({ user: res.data })
})
}
componentDidMount() {
this.getAllUsers()
}
handleChange = event => {
const newUser = { ...this.state.newUser };
newUser[event.target.name] = event.target.value;
this.setState({ newUser: newUser});
}
handleSubmit = event => {
event.preventDefault()
axios.post('/api/users', this.state.newUser)
.then(res => {
this.props.history.push(`/users/${res.data._id}`)
})
}
render() {
return (
<div>
{ /* This shows a list of All Users */ }
{this.state.user.map(user => (
<div key={user._id}>
<Link to={`/users/${user._id}`}>{user.name}</Link>
</div>
))}
<h1>New User Page</h1>
<form onSubmit={this.handleSubmit}>
<label>Name: </label>
<input
type="text"
name="name"
placeholder="Name?"
value={this.state.newUser.name}
onChange={this.handleChange}
/>
<label>Email: </label>
<input
type="text"
name="email"
placeholder="Email?"
value={this.state.newUser.email}
onChange={this.handleChange}
/>
<label>Favorite City: </label>
<input
type="text"
name="city"
placeholder="Favorite City?"
value={this.state.newUser.favoriteCity}
onChange={this.handleChange}
/>
<Button
type="submit"
value="Submit"
variant="contained"
color="primary"
>
Create User
</Button>
</form>
</div>
);
}
}
export default UserPage;
Please help.
Weird that email works fine, from what you posted your handleChange function is only updating the name on the newUser.
What you should see is what you type in all the inputs appear in the name input.
To fix this, you should probably have separate change handlers for each input:
handleNameChange
handleEmailChange
...
You should also consider storing name, email etc.. at the root of your state instead of nesting them in an object, that'll simplify the handler functions code.

Categories

Resources