How to add data to state object in react? - javascript

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
},
}));

Related

how can I implement a form validation in react js?

As seen in the title, I need a form validation in accordance below code. I have tried to validate many times with nodemailer method before and it was working validation. Now I changed my method due to some issues therefore I try another method but I cant not implement that. Can anyone help me, please?
Here is my new contact form and its function.
const Form = () => {
function sendEmail(e) {
e.preventDefault();
emailjs
.sendForm(
'servxxxxxxxxxu',
'tempxxxxxxxxxxxxa',
e.target,
'userxxxxxxxxxxxxxxxxxxxx'
)
.then((res) => {
console.log(res);
})
.catch((err) => console.log(err));
}
return (
<div className="Contact">
<div className="wrapper">
<h1>Contact Form</h1>
<form onSubmit={sendEmail}>
<input
className="input-field"
type="text"
name="name"
placeholder="Name"
/>
<input
className="input-field"
type="text"
name="user_email"
placeholder="E-Mail"
/>
<textarea name="message" rows="4" placeholder="Message" />
<input type="submit" value="Send" />
</form>
</div>
</div>
);
};
export default Form;
This is my old validation, may be helpful to you.
const initialState = {
name: '',
subject: '',
email: '',
message: '',
sent: false,
nameError: '',
subjectError: '',
emailError: '',
messageError: '',
};
export default class Validation extends React.Component {
state = initialState;
handleName = (e) => {
this.setState({
name: e.target.value,
});
};
handleSubject = (e) => {
this.setState({
subject: e.target.value,
});
};
handleEmail = (e) => {
this.setState({
email: e.target.value,
});
};
handleMessage = (e) => {
this.setState({
message: e.target.value,
});
};
validate = () => {
let nameError = '';
let subjectError = '';
let emailError = '';
let messageError = '';
if (!this.state.name) {
nameError = 'Name cannot be blank!';
}
if (!this.state.subject) {
subjectError = 'Subject cannot be blank!';
}
if (this.state.message.length < 5) {
messageError = 'Message cannot be less 5 character!';
}
if (!this.state.email) {
emailError = 'E-mail cannot be blank!';
} else if (typeof this.state.email !== 'undefined') {
var mailformat = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!mailformat.test(this.state.email)) {
emailError = 'Incorrect e-Mail!';
}
}
if (emailError || nameError || subjectError || messageError) {
this.setState({ emailError, nameError, subjectError, messageError });
return false;
}
return true;
};
handleSubmit = (e) => {
e.preventDefault();
const isValid = this.validate();
if (isValid) {
console.log(this.state);
this.sendingMail();
this.setState(initialState);
}
};
sendingMail = () => {
let data = {
name: this.state.name,
subject: this.state.subject,
email: this.state.email,
message: this.state.message,
};
axios
.post('http://127.0.0.1:3001/api/form', data)
.then((res) => {
this.setState(
{
sent: true,
},
this.resetForm()
);
})
.catch(() => {
console.log('message not sent');
});
};
resetForm = () => {
this.setState({
name: '',
subject: '',
email: '',
message: '',
});
setTimeout(() => {
this.setState({
sent: false,
});
}, 3000);
};
}
you can merge all handle methods into 1
state = initialState;
handleInput = (e , stateName) => {
this.setState({ [`${stateName}`]: e.target.value})
};
with this jsx
<input type="text" placeholder="name" onChange={(e)=>{this.handleInput('name' ,e)}}
validation
var States = [ this.state.name, this.state.subject , this.state.email , this.state.message]
States.forEach((stateKey)=>{
if (!stateKey) this.setState({Error: `${stateKey} could not be blank`})
})
if (this.state.message.length < 5)this.setState({Error:'Message cannot be less 5 character!})
if (this.state.Error) return false;
return true

the email and password don't get passed to firebase through the states

I get the error:email is badly formatted whenever I use the login form and the password doesn't get to firebase too
here's the error screenshot:
here
here's the code for the login form:
class LoginView extends React.Component {
constructor(props) {
super(props);
this.state = {
email : '',
password: '',
name:'',
phone:'',
fontsLoaded:false,
isLoading: false,
}
}
async componentDidMount(){
await Font.loadAsync({
'comfortaa':require('./assets/fonts/Comfortaa/static/Comfortaa-Bold.ttf'),
});
this.setState({fontsLoaded:true})
}
updateInputVal = (val, prop) => {
const state = this.state;
state[prop] = val;
this.setState(state);
}
registerUser = () => {
if(this.state.email === '' && this.state.password === '') {
Alert.alert('Enter details to signup!')
} else {
this.setState({
isLoading: true,
})
console.log(this.state.email);
firebase
.auth()
.createUserWithEmailAndPassword(this.state.email, this.state.password)
.then((res) => {
res.user.updateProfile({
name: this.state.name
})
console.log('User registered successfully!')
this.setState({
isLoading: false,
name: '',
email: '',
password: ''
})
this.props.navigation.navigate('Login')
})
.catch(error => {
this.setState({ errorMessage: error.message });
console.log(`Exception in registerUser:${error.message}`);
})
}
}
any idea to fix that error and the password error?

Reactstrap Form Input innerRef coming back null

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

React and checking condition after passing function through props

I'm fighting with my app since long time and slowly there is progress however I have still problem with one thing
I want to pass function thought props from Form Component to List component, after that I wish to check if button add was clicked if yes then I wish to launch function getMovie() inside List component and send another request to json database. with edit and remove it works as there are in same component, with adding button it is a bit more tricky.
the problem is that if I write just
else if (this.props.addClick) {
this.getMovie();
}
it's keep sending requests to database over and over
below is my code
Form Component
class Form extends React.Component {
constructor(props) {
super(props)
this.state = {
name: '',
type: '',
description: '',
id: '',
movies: [],
errors: "",
}
}
handleSubmit = e => {
e.preventDefault()
const url = `http://localhost:3000/movies/`;
if (this.state.name != "" && this.state.type != "" && this.state.description != "") {
axios
.post(url, {
name: this.state.name,
type: this.state.type,
description: this.state.description,
id: this.state.id,
})
.then(res => {
this.setState({
movies: [this.state.name, this.state.type, this.state.description, this.state.id]
})
})
.then(this.setState({
isButtonRemoveClicked: true
}))
}
else {
this.setState({
errors:"Please, Fill all forms above"
})
}
}
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type="text" placeholder="Movie" onChange={this.handleChangeOne}/>
<input type="text" placeholder="Type of movie" onChange={this.handleChangeTwo}/>
<textarea placeholder="Description of the movie"
onChange={this.handleChangeThree}></textarea>
<input id="addMovie" type="submit" value="Add movie" ></input>
<p>{this.state.errors}</p>
</form>
<List removeClick={this.handleRemove} editClick={this.editMovie} addClick={this.handleSubmit}/>
</div>
)
List Component
class List extends React.Component {
constructor(props) {
super(props)
this.state = {
movies: [],
isButtonRemoveClicked: false,
}
}
componentDidMount() {
this.getMovie()
}
componentDidUpdate() {
if (this.state.isButtonRemoveClicked === true) {
this.getMovie();
this.timer = setTimeout(() => {
this.setState({
isButtonRemoveClicked: false
})
}, 10)
}
else if (this.props.addClick === true) {
this.getMovie();
}
}
componentWillUnmount() {
clearTimeout(this.timer)
}
getMovie = () => {
const url = `http://localhost:3000/movies`;
axios
.get(url)
.then(res => {
const movies = res.data;
this.setState({
movies: movies,
})
})
.catch((err) => {
console.log(err);
})
}
There is nothing magical ;)
You're start loading data from componentDidUpdate() ... data loads, componentDidUpdate is fired again, again...
Don't handle events this way.
If your main objective is to call function in child component from parent component, then you can use refs.
Example in your code :-
class Form extends React.Component {
constructor(props) {
super(props)
this.state = {
name: '',
type: '',
description: '',
id: '',
movies: [],
errors: "",
}
}
handleSubmit = e => {
e.preventDefault()
const url = `http://localhost:3000/movies/`;
if (this.state.name != "" && this.state.type != "" && this.state.description != "") {
axios
.post(url, {
name: this.state.name,
type: this.state.type,
description: this.state.description,
id: this.state.id,
})
.then(res => {
this.setState({
movies: [this.state.name, this.state.type, this.state.description, this.state.id]
})
})
.then(
this.list.getMovie(); // call child function here
this.setState({
isButtonRemoveClicked: true
}))
}
else {
this.setState({
errors:"Please, Fill all forms above"
})
}
}
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type="text" placeholder="Movie" onChange={this.handleChangeOne}/>
<input type="text" placeholder="Type of movie" onChange={this.handleChangeTwo}/>
<textarea placeholder="Description of the movie"
onChange={this.handleChangeThree}></textarea>
<input id="addMovie" type="submit" value="Add movie" ></input>
<p>{this.state.errors}</p>
</form>
<List
ref={list => this.list=list } // Create ref here
removeClick={this.handleRemove}
editClick={this.editMovie}
addClick={this.handleSubmit}/>
</div>
)
And in list component no need to use componentDidUpdate getMovie() call.
class List extends React.Component {
constructor(props) {
super(props)
this.state = {
movies: [],
isButtonRemoveClicked: false,
}
}
componentDidMount() {
this.getMovie()
}
getMovie = () => {
const url = `http://localhost:3000/movies`;
axios
.get(url)
.then(res => {
const movies = res.data;
this.setState({
movies: movies,
})
})
.catch((err) => {
console.log(err);
})
}
I think you are handling events in an overcomplicated manner. Why don't you lift props from inside the List component and just trigger the desired behaviour in the Form?. For example:
class List extends React.Component {
handleAddClick() {
this.props.onAddClick()
}
handleEditClick() {
this.props.onEditClick()
}
handleRemoveClick() {
this.props.onRemoveClick()
}
render() {
return (
<div>
<button onClick={() => this.handleAddClick()}>Add</button>
<button onClick={() => this.handleEditClick()}> Edit</button>
<button onClick={() => this.handleRemoveClick()} > Remove</button>
</div>
})
}
and
class Form extends React.Component {
getMovie() {
// Make AXIOS request
}
handleAdd() {
this.getMovie();
}
handleRemove() {
// REMOVE CODE
}
handleEdit() {
// EDIT CODE
}
render() {
<form>
{/* Form elements */}
<List
onAddClick={() => this.handleAdd()}
onRemoveClick={() => this.handleRemove()}
onEditClick={() => this.handleEdit()}
/>
</form>
}
}

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: '',
}))
}

Categories