Form.Control type password in React-Bootstrap always renders an default password that i can't remove - reactjs

I am doing the login page and i realized i cannot set the default values of the Form.Control type password input!!!
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: 'thisIsMyDefaultPassword',
isLoading: false,
redirectToReferrer: false
};
}
handleChange = name => event => {
let update = {};
update[`${name}`] = event.target.value;
this.setState(update);
}
handleFocus = () => {
this.setState({ password: '' });
}
handleSubmit = () => event => {
let data = {
email: this.state.email,
password: this.state.password
}
this.props.login(data)
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('componentDidUpdate');
let { currentUser } = this.props;
console.log('currentUser ', currentUser, 'prevProps.currentUser ', prevProps.currentUser );
if (JSON.stringify(prevProps.currentUser) !== JSON.stringify(currentUser)) {
console.log('currentUser !=');
if (currentUser._id) {
this.setState({
redirectToReferrer: true
})
}
}
}
render() {
let { email, password , isLoading, redirectToReferrer } = this.state;
console.log('password when rendered', password);
if (redirectToReferrer) {
return <Redirect to={'/'} />;
}
return (
<div className="loginWrapper">
<div className="loginContainer">
<Form>
<Form.Group controlId="formGroupEmail">
<Form.Label>Email Address</Form.Label>
<Form.Control
type="email"
value={email}
onChange={this.handleChange('email')}
placeholder="Enter Email"
/>
</Form.Group>
<Form.Group controlId="formGroupPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
defaultValue={this.state.password}
onFocus={this.handleFocus}
onChange={this.handleChange('password')}
placeholder="Password"
/>
</Form.Group>
</Form>
<Button
variant="primary"
size="lg"
disabled={isLoading}
onClick={this.handleSubmit()}
block
>
{isLoading ? 'Loading…' : 'LOGIN'}
</Button>
</div>
</div>
);
}
}
i expect the default values rendered to be controlled by the default state of my component. But it just don't work. I have tried defaultValue / value / and defaultValue with value. but there is still this default number being rendered in the password input .. The above are my latest codes i am still facing the problem although i crack it with onFocus. If there's any better improvement to my codes please comment below too. An Advance thank you to all commenters. really appreciate the help of this community.
Below are the console logs for console.log('password when rendered', password) IT shows that react-bootstrap javascript is clearning the password and setting as 0346:
password when rendered thisIsMyDefaultPassword
Login.js:51 password when rendered
Login.js:51 password when rendered 0346
Thus concluding that the defaultValue for the type password does not work ?

The value props is too much here, if you get rid of it, you can change the input.
Additionally, you always provide the string "password" to your onChange handler as a value. This might not be what you want to do, but instead using the actual password the user is entering.
In your render method:
<p>Current password: {this.state.password}</p>
<Form>
<Form.Group controlId="formGroupPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
defaultValue={this.state.password}
onChange={this.handleChange('password')}
placeholder="Password"
/>
</Form.Group>
</Form>
And your handleChange function could look like:
handleChange = name => event => {
this.setState({ password: event.target.value });
};
Example: https://codesandbox.io/s/8x8zw28nv2

There are two type of valued components(TextField, Checkbox, etc.):
Controlled - The component whose value is controlled by the code implementation. In this type of component you have to set value prop of the component with the value source and handle it's onChange to get the value and update in the future source.
<TextField value={this.state.password}
onChange={(event) => this.setState({ password: event.target.value })}
/>
Un-controlled - The component which has a default value and that value can changed without any trigger/handling in the component code. These components have a prop 'defaultValue' populated with the initial value you want to assign.
<TextField defaultValue={this.state.password} />
You can't use both value and defaultValue on same component.
In your case You have to remove defaultValue prop, as you need a controlled component to make its value persist.

You have the same value for defaultValue and value, seems like it doesn't make sense because if value has a value, that value will be rendered. Try matching defaultValue to another value or just remove defaultValue.
Does your onChange work? Seems like not. Are you implemented your handleChange? Because you are using controlled inputs.
Try this:
handleChange = e => {
this.setState({
password: e.target.value
})
}
<Form>
<Form.Group controlId="formGroupPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
value={password}
onChange={this.handleChange}
placeholder="Password"
/>
</Form.Group>
</Form>

Related

React state sets the same value to all of the state values

I'm new to react JS, I'm trying to get the values from a form, and send it to a node JS middleware.
I set up two values in the state, one for the email and another one for the password. I set the state for both values in the set state method.
class LoginForm extends Component {
constructor(props){
super(props)
this.state = {
email : '',
password : '',
}
}
handleChange = (e) => {
this.setState({ email : e.target.value, password : e.target.value})
}
handleSubmit = (e) => {
console.log('state', this.state)
};
render () {
return (
<div style = {styles.form} >
<Fragment>
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={this.handleSubmit}
>
<Form.Item
name="email"
rules={[
{
type: 'email',
message: 'The input is not valid E-mail!',
},
{
required: true,
message: 'Please input your E-mail!',
},
]}
hasFeedback
>
<Input
placeholder={t`Email`}
value={this.state.email}
onChange={this.handleChange} />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true }]} hasFeedback
>
<Input.Password
placeholder={t`Password`}
value={this.state.password}
onChange={this.handleChange}
/>
</Form.Item>
<Button
type="primary"
htmlType="submit"
>
<span style = {styles.button} >Sign in</span>
</Button>
</Form>
</Fragment>
</div>
)
}
}
}
I created the handle submit function and linked it to the onsubmit method inside the form and tried console logging the current state of my values inside the handle submit function. To my surprise the value from the password gets console logged for the value email too. Like this
state {email: "123", password: "123"}
I cannot figure out what am I doing wrong.
I think if you change your handleChange function to this, it should work.
handleChange = (e) => {
this.setState({ [e.target.id] : e.target.value})
}
And add id to the input fields like this
<Input id="email" placeholder={t`Email`} value={this.state.email} onChange {this.handleChange} />
<Input.Password id="password" placeholder={t`Password`} value {this.state.password} onChange={this.handleChange} />
Here is the solution:
handleChange = (e) => {
let email = ''
let password = ''
if (e.target.name === 'email') {
email = e.taget.value
} else {
password = e.taget.value
}
this.setState({ email, password})
}

React Boostrap input form doesn't give any value

Hi everybody Tring to make a form with Form provided by bootstap but it doesn't work.
If I insert value it doesn't let me type, without value I digit but I can't get the value.
(I have also a Gatsby theme activated)
const StandAdd = () => {
const [item, setItem] = useState({
title: "",
kindof: "",
website: "",
image01: "",
image02: "",
image03: "",
})
const { title, kindof, website, image01, image02, image03 } = item
const handleInputChange = event => {
event.preventDefault()
setItem({ ...item, [event.target.name]: event.target.value })
}
const handleSubmit = event => {
event.preventDefault()
alert(`${title} ${item} ${website}`) // always empty I gat get anything
}
return (
<Layout>
<form onSubmit={handleSubmit}>
<Form>
<Form.Group controlId="title">
{/* <Form.Label>Email address</Form.Label> */}
<Form.Control
value={titlet} // <-- this blocks the typing
type="text"
placeholder="Enter Stand's Name"
onChange={handleInputChange}
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</form>
</Layout>
)
}
export default StandAdd
Any idea?
The issue is here:
<Form.Control
value="title" // <-- this blocks the typing
type="text"
placeholder="Enter Stand's Name"
onChange={handleInputChange}
/>
here you have to provide the name attribute so that your code:
setItem({ ...item, [event.target.name]: event.target.value })
will get some value in event.target.name.
So after adding name the code will be like:
<Form.Control
type="text"
name="title" <---- name added here
placeholder="Enter Stand's Name"
onChange={handleInputChange}
/>
And don't provide a hard-coded value to input like this:
value="title"
instead use defaultValue for providing an initial value.
I think you need to provide name attribute to <Form.Control> component.

how to perform crud operation in react with firebase database

I am trying on trial and error basis. I tried to insert username and password in the database using reactjs by event handling, but whenever I enter the username and the password both fields get the same value. For example, if I put 'ABC' as username and 123 as password then the username and password will get same value 123 in the database.
1.trying to insert data using event handling.
class Login extends Component{
ref = firebase.firestore().collection('login');
state = {
username: '',
password: ''
};
handleChange = (event) => {
const state = this.state
state.username = event.target.value;
state.password=event.target.value;
//console.log(state[event.target.username]);
//console.log(state[event.target.password]);
this.setState({username:state.username,
password:state.password });
console.log(state.username);
console.log(state.password);
}
onSubmit = (event) => {
event.preventDefault();
const { username,password } = this.state;
this.ref.add({
username,
password
}).then((docRef) => {
this.setState({
username: '',
password:''
});
this.props.history.push("/")
})
.catch((error) => {
console.error("Error adding document: ", error);
});
}
render()
{
return(
<form onSubmit={this.onSubmit}>
<div className="container mt-5 w-50">
<div className="form-group">
<label for= "user name" className="">User Name:</label>
<input type="text" name="userName" placeholder="UserName" className="form-control w-50" onChange={this.handleChange.bind(this)}/><br/>
<label for="password" className="">Password:</label>
<input type="password" name="password" placeholder="password" className="form-control w-50" onChange={this.handleChange.bind(this)}/><br/>
<button name="Login" className="btn btn-success w-50 mb-3">Login</button><br/>
{/* Don't Have an Account? SignUp */}
<Link to="/signup">Don't Have an Account? SignUp</Link>
</div>
</div>
</form>
);
}
}
export default Login;
username and password should get their actual values.
I believe this is because you are setting the state of both to the same value (event.target.value) in your event handler. You're also mutating state which is not a good thing to do in any situation.
in your handleChange function you are changing username AND password state values to the value of event.target.value which will happen when onChange fires in whichever input you are using handleChange as a listener.
change your handleChange function to this:
handleChange = event => {
let {name, value} = event.target;
this.setState({
[name]: value
});
}
by using {[name]: value} when the event fires in an input with name="password" the password value in your component's state will update
Your render function is a bit confusing but I am going to assume you're rendering a form with labels for username and password...
then in your input within your form (which I can't see in your markdown above, but I'm assuming is in the Login component):
<input name="username" value={this.state.username} onChange={this.handleChange} />
<input name="password" value={this.state.password} onChange={this.handleChange} />

React Native onChangeText like onChange in ReactJS

I learn in the same time ReactJS and React Native. I saw in an udemy tutorial something very beautiful, that the professor putt it just one onChange method, for all inputs and taking advantage of the "name" attribute, he could do this:
const onChange = event =>
setFormData({ ...formData, [event.target.name]: event.target.value });
So he said, instead of having for each onChange, inside of each input, a different method, we can have only one.
This is the code that I'm talking about:
const Register = props => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = event =>
setFormData({ ...formData, [event.target.name]: event.target.value });
const onSubmit = async event => {
event.preventDefault();
if (password !== password2) {
props.setAlert('Passwords do not match', 'danger', 5000);
} else {
props.registerUser({ name, email, password });
}
};
if (props.isAuthenticated) {
return <Redirect to="/dashboard" />;
}
return (
<Fragment>
<h1 className="large text-primary">Sign Up</h1>
<p className="lead">
<i className="fas fa-user" /> Create Your Account
</p>
<form className="form" onSubmit={event => onSubmit(event)}>
<div className="form-group">
<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={event => onChange(event)}
/>
</div>
<div className="form-group">
<input
type="email"
placeholder="Email Address"
name="email"
value={email}
onChange={event => onChange(event)}
/>
<small className="form-text">
This site uses Gravatar so if you want a profile image, use a
Gravatar email
</small>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
// minLength="6"
value={password}
onChange={event => onChange(event)}
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
value={password2}
onChange={event => onChange(event)}
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? <Link to="/login">Sign In</Link>
</p>
</Fragment>
);
};
In React Native, that is with a different professor, I tried to think how to do this. I tried a few days the offered props from the TextInput but non of then, in my opinion, can be used how we can use the "name" attribute in ReactJS.
This is the code for the React Native app:
import React, { Component } from 'react';
import {
StyleSheet,
View,
Button,
TextInput,
} from 'react-native';
class PlaceInput extends Component {
state = {
userName: '',
placeName: ''
}
userNameChangeHandler = (value) => {
this.setState({ userName: value })
}
placeNameChangeHandler = (value) => {
this.setState({ placeName: value })
}
placeSubmitHandler = () => {
if (this.state.placeName.trim() === '') {
return;
}
this.props.onPlaceAdded(this.state.placeName)
}
render() {
return (
<View style={styles.inputContainer}>
<TextInput
style={styles.placeInput}
value={this.state.userName}
onChangeText={this.userNameChangeHandler}
placeholder='User Name' />
<TextInput
style={styles.placeInput}
value={this.state.placeName}
onChangeText={this.placeNameChangeHandler}
placeholder='Beautiful place' />
<Button title='Add' style={styles.placeButton} onPress={this.placeSubmitHandler} />
</View>
);
}
};
Please someone help me to understand: it is possible to have one onChangeText method in React Native, like the professor from ReactJS did with onChange?
Try passing input "name" as a value to the handler function.
Like so:
import React, { Component } from 'react';
import {
StyleSheet, View, TextInput,
} from 'react-native';
class PlaceInput extends Component {
state = {
userName: '',
placeName: ''
}
handleInputChange = (inputName, inputValue) => {
this.setState(state => ({
...state,
[inputName]: inputValue // <-- Put square brackets
}))
}
render () {
return (
<View style={styles.inputContainer}>
<TextInput
style={styles.placeInput}
value={this.state.userName}
onChangeText={value => this.handleInputChange('userName', value)}
placeholder='User Name' />
<TextInput
style={styles.placeInput}
value={this.state.placeName}
onChangeText={value => this.handleInputChange('placeName', value)}
placeholder='Beautiful place' />
</View>
);
}
};
For that type of a function you are using the wrong prop. While onChangeText is all fine, it takes as its parameter a function with a single parameter: the changed text. Because of that you cannot do it with the onChangeText.
However, there exists another prop called onChange. This one supplies the following object as the parameter per the documentation: { nativeEvent: { eventCount, target, text} }. Target here, while could be used, is going to be just a number.
What would I suggest?
Instead of trying to handle it through the event.target.name change your function to take a second argument: name. After that you should call your functions as follows;
onChangeText={text => this.inputChangeHandler(text, 'name')}
This will create a function whose sole purpose is to supply the second parameter, allowing you to use just one function for all your text changes.

Submitting redux form values

I am new to react and redux technology. now started building an application that contains several redux forms. We want to submit simple form with values.
For ex: login form
Username : text input field
Password: text input field
Submit button
After entering values in fields and click on submit button i want to get the username and password field values in object or json data .. so that I can store it to my server with POST method.
Right now we are using handleSubmit(), but data is not coming as object
1 - The best practice to deal with input values are making them controlled. Which means :
Instead of
<input type='password' />
You do :
<input
type='password'
value={password}
onChange={ event => myInputHandler( event.target.value ) }
/>
The value might come from your state, redux state or as a props etc.
Your handler function differs according to where you store it.
I will give you an example with react state :
<input
type='password'
value={this.state.password}
onChange={ event => this.setState({ password : event.target.value }) }
/>
So whenever someone types, your onChange handler will be called, so that your react state will update with the input ( event.target.value ).
2 - If you need these values when a user submits, then you need to wrap these input fields within a form element and attach a onSubmit handler.
onSubmitHandler( event ){
event.preventDefault()
let password = this.state.password
// use password or other input fields, send to server etc.
}
<form onSubmit={ event => this.onSubmitHandler(event) }>
<input
type='password'
value={this.state.password}
onChange={ event => this.setState({ password : event.target.value }) }
/>
</form>
Hope you get what you need.
If you are using redux to store state then use redux-from then use redux from
import React from 'react'
import {Field, reduxForm} from 'redux-form'
const SimpleForm = props => {
const {handleSubmit, submitting} = props return (
<form onSubmit={handleSubmit(e=>console.log('your form detail here', e))}>
<div>
<label>First Name</label>
<div>
<Field name="firstName" component="input" type="text" placeholder="First Name" />
</div>
</div>
<div>
<label>Last Name</label>
<div>
<Field name="lastName" component="input" type="text" placeholder="Last Name" />
</div>
</div>
<div>
<button type="submit" disabled={pristine || submitting}>Submit</button>
</div>
</form>
) }
export default reduxForm({ form: 'simple'})(SimpleForm)
Go here for more detail
https://redux-form.com
I put the name of the input as the key that I want to use.
Then each time the input changes I destructure the event passed to the onChange function, and I use the name,value to update the state.
On form submit make sure to use preventDefault(); in order to avoid the page refreshing.
import React, { Component } from 'react'
class FormExample extends Component {
constructor(props){
super(props)
this.state = {
formData: {}
}
}
handleInputChange = ({ target: { name,value } }) => {
this.setState({
formData: {
...this.state.formData,
[name]: value
}
})
}
handleFormSubmit = e => {
e.preventDefault()
// This is your object
console.log(this.state.formData)
}
render() {
return(
<div>
<Form
handleSubmit={this.handleFormSubmit}
handleChange={this.handleInputChange}
/>
</div>
)
}
}
const Form = ({ handleSubmit, handleChange }) => (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} name="username" type="text" placeholder="Username" />
<input onChange={handleChange} name="password" type="password" placeholder="Password" />
<button>Submit</button>
</form>
)
export default FormExample

Resources