Reactstrap Form Input innerRef coming back null - javascript

Trying to send input data to console.log but it doesn't seem to be working correctly. I'd like to be able to log into console email and password from auth.
Here is my constructor and onChange:
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
errors: {}
};
this.onChange = this.onChange.bind(this);
}
onChange = e => {
this.setState({
[e.target.id]: e.target.value
});
}
Here is my onSubmit:
onSubmit = e => {
e.preventDefault()
const userData = {
email: this.state.email,
password: this.state.password
};
console.log(userData);
}
Here is my Input from Form:
<Input
name="email"
type="email"
onChange={this.onChange}
innerRef={this.state.email}
error={errors.email}
/>
Not getting any errors, just email and password are coming back as null.

You have to change the onChange function to this :
onChange = e => {
this.setState({
[e.target.name]: e.target.value
});
}
I think this have to solve your problem

Related

Best way to set state of object using dynamic key name? - reactjs

I have a react state like:
this.state = {
formInputs: {
username: '',
password: '',
passwordConfirm: '',
},
handleChange = () => {
const {target: {name, value}} = event;
this.setState({
[name as keyof formInputs]: value
});
}
};
How can I change this line ( [name as keyof formData]: value) to a JavaScript instead of Typescript?
We can use Computed property names concept to compute the object property name dynamically. For that we need to put the expression inside [].
When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name.
For your state
this.setState({
formInput: {
...this.state.formInput,
[event.target.name]: event.target.value
}
})
Sandbox for your reference: https://codesandbox.io/s/react-basic-example-p7ft8
import React, { Component } from "react";
export default class Login extends Component {
state = {
formInputs: {
email: "",
password: ""
}
};
handleOnChange = event => {
this.setState({
formInput: {
...this.state.formInput,
[event.target.name]: event.target.value
}
});
};
render() {
return (
<form>
<label>Email</label>
<input type="text" name="email" onChange={this.handleOnChange} />
<label>Password</label>
<input type="password" name="password" onChange={this.handleOnChange} />
</form>
);
}
}
You can directly use Bracket_notation
[name]: value
In your case, { formInput: { username:"", password: "" }
this.setState({
formInput: {
...this.state.formInput,
[name]: value
}
});
I think you can initialize your formObject as empty json and
this.state = {formInput: {}}
Later onChange you can set the value something like
this.setState({formInput[event.target.name]: event.target.value})
and conditionaly check if (this.state.formInput.username) ? this.state.formInput.username : '' to value

How to add data to state object in react?

I created this.state.data object. Now I need to put this.state.email and this.state.password into this.state.data.email2 and this.state.data.password2
I want to create local storage. To do that I need an object where I could store data. this.state.email and this.state.password are inputs.
class Register extends Component {
constructor(props){
super(props);
this.state = {
email: '',
password: '',
data: {
email2: '',
password2: '',
},
}
// This binding is necessary to make `this` work in the callback
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleEmailChange = (event) => {
this.setState({email: event.target.value});
}
handlePasswordChange = (event) => {
this.setState({password: event.target.value});
}
handleSubmit = (event) => {
event.preventDefault();
console.log(this.state.email);
console.log(this.state.password);
/*
Take values from input, ant put it into this state data array
*/
// Reset form;
this.setState({
email: '',
password: '',
})
}
When I activate handleSubmit method I expect to take this.state.email, and this.state.password. And put it into object this.state.data
Hope you need to pass this.state.email and this.state.password to this.state.data
You can do that in handleEmailChange and handlePasswordChange itself, and your using arrow functions, so don't need to bind this in constructor.
Check a code below:
class App extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
data: {
email2: '',
password2: '',
},
}
}
handleEmailChange = (event) => {
this.setState({
email: event.target.value,
data: {
...this.state.data,
email2: event.target.value,
}
});
}
handlePasswordChange = (event) => {
this.setState({
password: event.target.value,
data: {
...this.state.data,
password2: event.target.value,
}
});
}
handleSubmit = (event) => {
event.preventDefault();
console.log(this.state.email);
console.log(this.state.password);
console.log('object data');
console.log(this.state.data);
/*
Take values from input, ant put it into this state data array
*/
// Reset form;
this.setState({
email: '',
password: '',
}, () => console.log(this.state))
}
render() {
return (
<div>
<input type="text" onChange={this.handleEmailChange} value={this.state.email} />
<br/><br/>
<input type="text" onChange={this.handlePasswordChange} value={this.state.password} />
<br/><br/>
<button type="button" onClick={this.handleSubmit}>Submit</button>
</div>
);
}
}
Working demo
and don't need to write separate events for similar functionalities, Check the demo once, you can do it like below:
<input type="text" data-field = "email" onChange={this.handleChange} value={this.state.email} />
<input type="text" data-field = "password" onChange={this.handleChange} value={this.state.password} />
and in handleChange
handleChange = (event) => {
this.setState({
[event.target.getAttribute('data-field')]: event.target.value,
data: {
...this.state.data,
[`${event.target.getAttribute('data-field')}2`]: event.target.value,
}
});
}
Hope this helps.
Like this (assuming your setup supports spread operator ... )
handleEmailChange = event => {
this.setState({ email: event.target.value });
this.setState(prevState => ({ data: { ...prevState.data, email2: event.target.value } }));
};
handlePasswordChange = event => {
this.setState({ password: event.target.value });
this.setState(prevState => ({ data: { ...prevState.data, password2: event.target.value } }));
};
You can do like this
handleSubmit = (event) => {
event.preventDefault();
console.log(this.state.email);
console.log(this.state.password);
const {data} = this.state;
data.email2 = this.state.email;
data.password2 = this.state.password;
this.setState({ data });
// Reset form;
this.setState({
email: '',
password: '',
})
}
or without mutating the state (good practice)
this.setState(prevState => ({
data: {
...prevState.data,
[data.email2]: this.state.email
[data.password2]: this.state.password
},
}));

React onchange event: this.setState() not setting state?

I am trying to set state via this.setState() of username and password when user types a value in username and password field. I am using onChange event type
ISSUE: the state is not changing. I log this.state.data.username in the render().
import React, { Component } from "react";
import { Form, Button } from "react-bootstrap";
import { Link } from "react-router-dom";
var Joi = require("joi-browser");
class Login extends Component {
state = {
data: { username: "a", password: "b " },
errors: {
email: "ddsfds",
password: "aaaa"
}
};
schema = {
username: Joi.string()
.min(0)
.required()
.label("Username"),
password: Joi.string()
.required()
.label("Password")
};
handleSubmit = event => {
event.preventDefault();
console.log("submited.", event.target);
const { data } = this.state;
const { err } = Joi.validate(data, this.schema);
if (err) {
console.log("error is true", err);
} else {
console.log("not true");
}
};
handleEmailOnChange = event => {
const inputUsername = event.target.value;
console.log("input is...", inputUsername);
this.setState({ username: inputUsername });
};
handlePassword = event => {
const passwordInput = event.target.value;
this.setState({ password: passwordInput });
};
render() {
console.log("username ", this.state.data.username);
return (
<div id="form-wrapper">
<Form>
<Form.Group controlId="formBasicEmail">
<h4>Sign In</h4>
<Form.Control
type="email"
placeholder="Enter email"
onChange={this.handleEmailOnChange}
/>
{/* <span>{this.state.errors.username} </span> */}
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Control
type="password"
placeholder="Password"
onChange={this.handlePassword}
/>
</Form.Group>
<div id="register-wrapper">
<Link to="/register" type="button" className="btn btn-warning">
Register Account
</Link>
<Button
variant="primary"
className="m-2"
type="submit"
onClick={this.handleSubmit}
>
Submit
</Button>
</div>
</Form>
</div>
);
}
}
export default Login;
You aren't updating the state correctly or not using it correctly. The state in your constructor has data object with username and password
handleEmailOnChange = event => {
const inputUsername = event.target.value;
console.log("input is...", inputUsername);
this.setState(prev => ({data: {...prev.data, username: inputUsername } }));
};
handlePassword = event => {
const passwordInput = event.target.value;
this.setState(prev => ({data: {...prev.data, password: passwordInput } }));
};
The state you are changing is this.state.username, the one you console is this.state.data.username.
To set data in your state, use:
this.setState(prevState => ({
data: {
username: inputUsername,
...prevState.data
}
})

React JS How to reset a form

How do I reset the values in a form in React JS onClick?
class AddFriendForm extends Component {
constructor(props) {
super(props)
this.state = {
firstname: '',
lastname: '',
}
}
render() {
const { addFriend } = this.props
const setFirstName = add => this.setState({ firstname: add.target.value })
const setLastName = add => this.setState({ lastname: add.target.value })
return (
<div>
<div>
<Label label="First Name" />
<Field onChange={setFirstName} />
<Label label="Last Name" />
<Field onChange={setLastName} />
<SecondaryButton
name="Search"
onClick={() => addFriend(this.state)}
/>
<SecondaryButton
name="Reset"
onClick={() => ???}
/>
</div>
</div>
)
}
}
When the user presses the Reset button, I want an onClick event that resets all the fields in the form to blank. Is there a single line of code to do this?
First, create a function called resetForm
resetForm = () => {
this.setState({
...this.state,
firstname: '',
lastname: ''
})
}
Then trigger the function when reset button is clicked
onClick={this.resetForm}
Cheers mate
EDIT:
You have to assign the values to "Field" using value={this.state.firstname}
<Field value={this.state.firstname} onChange={...
Small tip: dont define your functions in your jsx code.
You can do this simply like this.
Before the render() add below part. This is a function to reset the fields.
reset = () => {
this.setState({ firstname: ''})
this.setState({ lastname: ''})
}
And this where the function is called. (In Button onPress.)
<Button
title='reset'
style={styles.button}
onPress={this.reset}
>
</Button>
Note:- use this one in functional component.
const handleReset = (e) => {
e.preventDefault();
setState(prevState => ({
...prevState,
name: '',
email: '',
password: ''
}))
}
handleReset = () => {
setState(({
name: '',
email: '',
}))
}

State of React.js component is not updated when browser auto-completes username

I have the following component in React:
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {username: '', password: '', redirectToReferrer: false};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const value = event.target.value;
const name = event.target.name;
this.setState({
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();
console.log('A name was submitted: ' + this.state.username);
Auth.authenticate(this.state.username, this.state.password, () => {
this.setState({ redirectToReferrer: true })
})
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/' } }
const { redirectToReferrer } = this.state
if (redirectToReferrer) {
return (
<Redirect to={from}/>
)
}
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<form id='loginForm'>
<input type="text" name="username" onChange={this.handleChange} />
<input type="password" name="password" onChange={this.handleChange} />
<button onClick={this.handleSubmit}>Log in</button>
</form>
</div>
)
}
}
When I use the browser auto-complete feature (instead of typing 'admin' I type just 'a' and let browser to fill the rest) the component's state is not update and it submits incorrect value. When I type the username/password all by hand it works correctly. How can I fix this? It's pretty common use case...
It looks like that some browsers have a bug.
You can try to workaround it with Autofill polyfill:
A polyfill to fire a change event when the browser auto fills form fields

Categories