Conditional rendering of a div based on state in react - javascript

Below is a authentication component that handles both registering and login of a user into an application. The approach used was to conditionally render a div based on whether a user had signed up in the application before or they are a new user. The div doesn't change based on the initial state and based on the conditions set. In this case, the isSignUp state is false therefore the user hasn't signed up before hence all the fields are supposed to be available for data input by the user but the fields have been ommited. Below is the code
const {isSignUp, setisSignUp} = useState(false);
<form onSubmit = {handleSubmit} className = 'form'>
{isSignUp && (
<div className='auth-form-field'>
<input
name="Full Name"
type="text"
placeholder="Full Name"
className = "form-input"
onChange={handleChange}
required
/>
</div>
)}
<div className='auth-form-field'>
<input
name="Email"
type="text"
placeholder="Email"
className = "form-input"
onChange={handleChange}
required
/>
</div>
{ isSignUp && (
<div className='auth-form-field'>
<input
name="User Name"
type="text"
placeholder="User Name"
className = "form-input"
onChange={handleChange}
required
/>
</div>)
}
<div className = 'auth-form-field'>
<input
name="Password"
type="password"
placeholder="Password"
className = "form-input"
onChange={handleChange}
required
/>
</div>
{isSignUp && (
<div className = 'auth-form-field'>
<input
name="Confirm Password"
type="password"
placeholder="Confirm Password"
className = "form-input"
onChange={handleChange}
required
/>
</div>)
}
</form>

Your syntax of useState is incorrect here
Correct syntax:
const [isSignUp, setisSignUp] = useState(false);

The Correct syntax to use useState is with square brackets, like this
const [isSignup, setIsSignUp] = useState(false);

Related

Setting formData with an object

Currently, i have this state with a formData.
Upon typing some text, instead to change the fullName.firstName. its making another property and just setting a single (as in single letter) value.
const [formData, setFormData] = useState({
fullName: {
firstName: "",
lastName: "",
},
email: "",
password: "",
confirmPassword: "",
});
This is how i set the formData.
const handleChange = (event) => {
const { value, name } = event.target;
console.log(name, value);
setFormData((prevFormData) => ({
...prevFormData,
[name]: value,
}));
};
This is my JSX, you may check the "name" attribute in input for some reference.
<div className="App">
<form onSubmit={onSubmit}>
<h1>Submit Form Nested Object UseState</h1>
<input
text="text"
placeholder="First Name"
name="firstName"
value={formData.fullName.firstName}
onChange={handleChange}
/>
<input
text="text"
placeholder="Last Name"
name="lastName"
value={formData.fullName.lastName}
onChange={handleChange}
/>
<input
text="email"
placeholder="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
<input
text="password"
placeholder="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
<input
text="password"
placeholder="confirm Password"
name="confirmPassword"
value={formData.confirmPassword}
onChange={handleChange}
/>
<button>Submit</button>
</form>
{JSON.stringify(formData, null, 2)}
</div>
Change the form names like so:
<form onSubmit={onSubmit}>
<h1>Submit Form Nested Object UseState</h1>
<input
placeholder="First Name"
name="fullName.firstName"
value={formData.fullName.firstName}
onChange={handleChange}
/>
<input
placeholder="Last Name"
name="fullName.lastName"
value={formData.fullName.lastName}
onChange={handleChange}
/>
<input
placeholder="email"
name="email"
value={formData.email}
onChange={handleChange}
/>
<input
placeholder="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
<input
placeholder="confirm Password"
name="confirmPassword"
value={formData.confirmPassword}
onChange={handleChange}
/>
<button>Submit</button>
</form>
then change your handleChange function to this:
const handleChange = (event) => {
const { value } = event.target;
const [key,subkey] = event.target.name.split('.');
setFormData((prevFormData) => ({
...prevFormData,
[key]: subkey ? {
...prevFormData[key],
[subkey]: value,
} : value
}));
};

Hide the react components in the form?

In the below form component how can we hide the certain input components ?
#1 how can we pass display: none to certain component?
#2 tried to set the state and mount but throwing errors while rendering.
const inputStyle = {
display:none
}
and pass the style = {inputStyle} to effect certain components
is there any effective way to condtionally render the below form and hide the different components for different domains?
import React from 'react'
class ClassComponentForm extends React.Component {
state = {}
componentDidMount(){
this.setState(emptyForm)
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
render(){
return(
<div id='classComponentForm'>
<h2>
Please Enter Your Information - Class
</h2>
<form id='form'>
<label htmlFor='nameInput'>
Name:
</label>
<input
id='nameInput'
name='name'
type='text'
placeholder='Please type your name'
value={this.state.name}
onChange={(e) => this.handleChange(e)}
/>
<label htmlFor='emailInput'>
Email:
</label>
<input
id='emailInput'
name='email'
type='text'
placeholder='Please type your email'
value={this.state.email}
onChange={(e) => this.handleChange(e)}
/>
<label htmlFor='zipcodeInput'>
Zipcode:
</label>
<input
id='zipcodeInput'
name='zipcode'
type='text'
placeholder='Please type your zipcode'
value={this.state.zipcode}
onChange={(e) => this.handleChange(e)}
/>
<label htmlFor='dateInput'>
Date:
</label>
<input
id='dateInput'
name='date'
type='date'
value={this.state.date}
onChange={(e) => this.handleChange(e)}
/>
</form>
</div>
)
}
}
export default ClassComponentForm
handleChange setup keys inside state object based on input name (because of e.target.name) which you defined in the input element. You already access this value inside the value prop
value={this.state.email}
The same thing can be used to conditionally hide each input. This is an example of how you can hide email input.
{this.state.email && <input
id='emailInput'
name='email'
type='text'
placeholder='Please type your email'
value={this.state.email}
onChange={(e) => this.handleChange(e)}
/>}

When ever I submit my form I get the form data in my URL instead of it posting to my backend

I am having an issue when I submit my form it puts all of the form data into my URL instead of sending it to my backend. I'm not sure what the issue is at first I thought it was because I didn't have a method="post" in the form tag but that didn't fix my issue because it tried to send the form data to localhost:3000/register instead of localhost:5000/register. Any help would be appreciated.
Bellow is my current Frontend code.
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'
import '../css/register.css';
import {IoMdArrowRoundBack} from 'react-icons/io'
import { useState } from 'react'
import axios, { Axios } from 'axios';
const Register = () => {
const [emailReg, setEmailReg] = useState("");
const [usernameReg, setUsernameReg] = useState("");
const [passwordReg, setPasswordReg] = useState("");
const register = () => {
Axios.post('http://localhost:5000/register', {
email: emailReg,
username: usernameReg,
password: passwordReg,
}).catch(function (error) {
console.log(error);
});
};
return (
<div className='background-image'>
<div className='back-button'>
<Link to='/'>
<IoMdArrowRoundBack id='back-arrow' />
<h3>Home</h3>
</Link>
</div>
<div className="container-wrapper">
<div className="container">
<h1>Create Account</h1>
<div className="wrapper">
<form>
<div className="textarea" id="email">
<input
type="email"
onChange={(e) => {
setEmailReg(e.target.value);
}}
name="email"
id="authentactor-email"
placeholder="Email"
defaultValue=""
required
/>
</div>
<div className="textarea" id="username">
<input
type="text"
onChange={(e) => {
setUsernameReg(e.target.value);
}}
name="name"
id="authentactor-text"
placeholder="Username"
defaultValue=""
required
/>
</div>
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
name="password"
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button id="button" onClick={register}>Create Account</button>
</div>
</form>
<div className='bottom-text-wrapper'>
<h4>Already have an account? <Link to='/login'>Login Here</Link></h4>
</div>
</div>
</div>
</div>
</div>
)
}
export default Register
According to HTML Living Standard
The missing value default and invalid value default are the Submit Button state.
You can find more information on this question but basically adding type="button" to your Create Account button should do the job.
(so something like <button id="button" type="button" onClick={register}>Create Account</button>)
I figured it out for some reason I can't have the "name" tag in my input fields like it is below.
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
name="password"
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button onClick={register} id="button">Create Account</button>
</div>
As soon as I removed the "name" tags I was able to POST my form to the backend and I only get a question mark in my url now instead of all the form data. To fix the question mark I had to set button type="button".
correct code below.
<div className="textarea" id="password">
<input
type="password"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
id="authentactor-password"
placeholder="Password"
defaultValue=""
required
/>
</div>
<div id="button-wrapper">
<button type="button" onClick={register} id="button">Create Account</button>
</div>

How to make onChange tracking function in functional component as in class component

Here is my class component
handleChange =(e) => {
this.setState({
[e.target.id]: e.target.value
})
}
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
As you can see we can track all the input with one function component.
But how to get the same result as that inside the functional component?
Now I am setting state for each element.
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={e =>setEmail(e.target.value)}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={e => setPassword(e.target.value)}/>
</div>
The update is similar. Given some state, data for example, then a handler may look like:
const handleChange = (e) => {
const { id, value } = e.target;
setData((data) => ({
...data,
[id]: value
}));
};
Use a functional state update to spread in the existing state and use the input's id and value from the onChange event to update that section of state.
Full code example
function App() {
const [data, setData] = useState({});
const handleChange = (e) => {
const { id, value } = e.target;
setData((data) => ({
...data,
[id]: value
}));
};
return (
<div className="App">
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={handleChange} />
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={handleChange} />
</div>
<div>Email: {data.email}</div>
<div>Password: {data.password}</div>
</div>
);
}
declare one state containing both email and pasword for your functional component as below :
let [loginInfo, setLoginInfo] = useState({email:'',password:''})
handleChange =(e) => {
setLoginInfo({
...loginInfo,
[e.target.id]: e.target.value
})
}
you form
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={handleChange}/>
</div>
You can create object of form input and assign it to a state like below
const [formInput, setFormInput] = useState({
email: "",
password: ""
});
And set it like this
const handleChange = (e) => {
setFormInput((prevState) => ({
...prevState,
[e.target.id]: e.target.value
}));
};
See this codesandbox code
const [input, setInput] = useState({email:"", password:""})
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" value={input.email}
onChange={e => setInput({...input,[e.target.id]: e.target.value}}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" value={input.password}
onChange={e => setInput({...input,[e.target.id]: e.target.value}}/>
</div>
You can try this code.
In this way you can handle both inputs using same state without handler

getting values from <Field> onSubmit using React.js and redux.

Hi I am learning Reactjs, redux, and I want to simply print to console.log the username and password for this form.
I have tried console.log(e.target.user.value) but I a getting no results.
here is the handle function.
and then the Form and 2 fields.
how can I print the value of username and password in the handleSubmit function ?
Try Below Code:
handleSubmit = values => {
console.log('values',values);
//Here you will get values in values.username & values.password
}
render(){
const { handleSubmit } = this.props;
return(
<form onSubmit={handleSubmit(this.handleSubmit)}>
<div className="form-inputs">
<Field type="text" label="Name" name="username" data-fieldname="username"
component={bootstrapFormField} placeholder="Username" />
<Field type="password" label="Password" name="password" data-
fieldname="password" component={bootstrapFormField}
placeholder="Password" />
</div>
<div className="form-actions text-right">
<button type="submit" className="btn btn-submit green">
Sign In
</button>
</div>
</form>
)
}

Categories