I've been trying to console.log these 2 inputs, but can't seem to figure it out, can anyone tell me what I've done wrong?
I keep getting the Cannot read property 'value' of null error
function printInputs() {
let username = document.getElementById('user').value
let password = document.getElementById('pass').value
console.log(username);
console.log(password);
}
function App() {
return (
<div className="App">
<h1>Log In</h1>
<h1>{code}</h1>
<form>
<input className='userInput' id='user' type='text' placeholder='username' /><br />
<input className='userInput' id='pass' type='password' placeholder='password' /><br />
<input className='userSubmit' type='submit' value='Log In' onSubmit={printInputs()} />
</form>
</div>
);
}
onSubmit={printInputs()}
You are trying to call printInputs immediately (before the render function has returned anything so before the inputs are in the page).
You need to pass a function to onSubmit:
onSubmit={printInputs}
That said, this is not the approach to take for getting data from forms in React. See the Forms section of the React guide for the right approach.
The way to write forms in react. Working example demo
function App() {
const [state, setState] = React.useState({ username: "", password: "" });
const handleSubmit = e => {
e.preventDefault();
console.log(state);
};
const handleChange = e => {
setState({
...state,
[e.target.name]: e.target.value
});
};
return (
<div className="App">
<h1>Log In</h1>
<form onSubmit={handleSubmit}>
<input
className="userInput"
name="username"
type="text"
placeholder="username"
onChange={handleChange}
/>
<br />
<input
className="userInput"
name="password"
type="password"
placeholder="password"
onChange={handleChange}
/>
<br />
<input className="userSubmit" type="submit" value="Log In" />
</form>
</div>
);
}
in the first never use real dom to manipulate the dom in
React ,use a state to get de value and the onSumbit is used in Form tag
import React, { useState } from "React";
const App = () => {
const [userName, setUserName] = useState("");
const [password, setPassword] = useState("");
const printInputs = () => {
console.log(userName);
console.log(password);
};
return (
<div className="App">
<h1>Log In</h1>
<form onSubmit={printInputs}>
<input
className="userInput"
id="user"
type="text"
placeholder="username"
onChange={event => setUserName(event.target.value)}
/>
<br />
<input
className="userInput"
id="pass"
type="password"
placeholder="password"
onChange={event => setPassword(event.target.value)}
/>
<br />
<input
className="userSubmit"
type="submit"
value="Log In"/>
</form>
</div>
);
};
export default App;
Related
I am working on Reactjs(Nextjs),Trying to submit form but unable to submit form,How can i submit form data ? Here is my current code
export default function Home() {
const checklogin = async (e:any) => {
e.preventDefault();
alert("Its working");
}
<form className="forms-sample" onSubmit={checklogin}>
<div className="form-group first">
<label htmlFor="username">Username</label>
<input
type="text"
className="form-control"
placeholder="your-email#gmail.com"
id="username"
/>
</div>
<div className="form-group last mb-3">
<label htmlFor="password">Password</label>
<input
type="password"
className="form-control"
placeholder="Your Password"
id="password"
/>
</div>
<input
type="submit"
name="submit"
defaultValue="Log In"
className="btn btn-block btn-primary"
/>
</form>
1. controlled form
import React from 'react';
export default function Home() {
const INITIAL_DATA = {
username: '',
password: '',
};
const [formData, setFormData] = React.useState(INITIAL_DATA);
const checklogin = async (e) => {
e.preventDefault();
console.log(formData); // * PROCESS FORMDATA ON SUBMIT
alert('Its working');
setFormData(INITIAL_DATA); // * CLEAR DATA AFTER SUBMIT
};
function handleOnChangeInput(event) {
const name = event?.target?.name;
const value = event?.target?.value;
setFormData((prev) => ({
...prev,
[name]: value,
}));
}
return (
<form className='forms-sample' onSubmit={checklogin}>
<div className='form-group first'>
<label htmlFor='username'>Username</label>
<input
type='text'
className='form-control'
placeholder='your-email#gmail.com'
id='username'
onChange={handleOnChangeInput}
value={formData?.username}
/>
</div>
<div className='form-group last mb-3'>
<label htmlFor='password'>Password</label>
<input
type='password'
className='form-control'
placeholder='Your Password'
id='password'
onChange={handleOnChangeInput}
value={formData?.password}
/>
</div>
<input
type='submit'
name='submit'
defaultValue='Log In'
className='btn btn-block btn-primary'
/>
</form>
);
}
2. Uncontrolled form
import React from 'react';
export default function Home() {
const formRef = React.useRef(null);
const checklogin = async (event) => {
event.preventDefault();
alert('Its working');
// * Get form enteries
const formData = new FormData(formRef?.current);
const formEnteries = Object.fromEntries(formData?.entries());
console.log(formEnteries); // * PROCESS FORMENTERIES ON SUBMIT
// * Clear form fields here
const formCurrentTarget = event?.currentTarget;
formCurrentTarget?.reset();
};
return (
<form className='forms-sample' onSubmit={checklogin} ref={formRef}>
<div className='form-group first'>
<label htmlFor='username'>Username</label>
<input
type='text'
className='form-control'
placeholder='your-email#gmail.com'
id='username'
name='username'
/>
</div>
<div className='form-group last mb-3'>
<label htmlFor='password'>Password</label>
<input
type='password'
className='form-control'
placeholder='Your Password'
id='password'
name='password'
/>
</div>
<input
type='submit'
name='submit'
defaultValue='Log In'
className='btn btn-block btn-primary'
/>
</form>
);
}
Read more about controlled and uncontrolled components here - Link
I am facing an issue with react , it worked with individual usestates but when I made it as an object it failed , and this is the code :
import React, { useState } from 'react'
import {Link} from "react-router-dom"
import {DatabaseNetworkPoint} from '#icon-park/react';
import axios from "axios"
export default function Register() {
const [user, setUser] = useState({
username:"",
email:"",
password:"",
age:0,
gender:"",
})
const [file, setFile] = useState(null)
const handleChange = (event) => {
console.log(event.target.value)
setUser({
username:event.target.value,
email:event.target.value,
password:event.target.value,
age:event.target.value,
gender:event.target.value,
img:event.target.files[0]
})
setFile(event.target.files[0])
}
const handleSubmit = (event) => {
event.preventDefault()
console.log('button clicked', event.target)
}
return (
<div className='container'>
<div className='left'>
<div className='logo'>
<DatabaseNetworkPoint theme="outline" size="150" fill="#333"/>
<h1>WonderHit</h1>
</div>
<form className='form' onSubmit={handleSubmit}>
<input placeholder='Username' value={user.username} className='field' type="text" onChange={handleChange} />
<input placeholder='Email' value={user.email} className='field' type="email" onChange={handleChange} />
<input placeholder='Password' value={user.password} className='field' type="password" onChange={handleChange} />
<input placeholder='Age' value={user.age} className='field' name='age' type="number" onChange={handleChange} />
<input placeholder='Gender' value={user.gender} className='field' name='gender' type="text" onChange={handleChange} />
<div className='profilePic'>
<div className='Photo'></div>
<input className='field2' id='file' type="file" onChange={handleChange} />
<label htmlFor = "file" className='uploadPic' >+</label>
</div>
<button className='submit' type="submit">Register</button>
<h3 className='routing'>You already have an account ? <Link className='rot' to="/">Login</Link></h3>
</form>
</div>
<img className='right' src='https://images.unsplash.com/photo-1562577309-4932fdd64cd1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80' />
</div>
)
}
and this is the error Iam getting :
Uncaught TypeError: Cannot read properties of null (reading '0')
what might be the problem ?? is it the file thats causing me issues ? should I handle it as string ??????
img:event.target.files[0]
You're calling handleChange for every <input>, whether it's a file type or not.
Use a different handler, don't use the same handler(handleChange) for every input change, the issue is coming because of another field change file type input returning null.
Use another handler for the upload file and set it to use of useState and use it for a later use case.
It's because this line setFile(event.target.files[0]) you should first check existing of event.target.files then set it in your state;
event.target.files && setFile(event.target.files[0])
Maybe you can add a check to your handleChange(event)'s event, and make a conditional setting to your user state. Also remember using new object when setting user state, because you would like to save the other input's state in your user
const handleChange = (event) => {
if(event.target.placeholder === 'Username'){
// 📌 use {...user, [update]: event.target.value }
setUser({...user, username:event.target.value });
}
//else if (){ ...other input}
if(event.target.id = 'file'){
setFile(event.target.files[0])
}
}
a simple example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
function App () {
const [user, setUser] = React.useState({});
const handleChange = (e) => {
if (e.target.placeholder === "Username") {
setUser({...user, username: e.target.value});
}
if (e.target.placeholder === "Email") {
setUser({...user, email: e.target.value});
}
if (e.target.placeholder === "Password") {
setUser({...user, password: e.target.value});
}
if (e.target.placeholder === "Age") {
setUser({...user, age: e.target.value});
}
if (e.target.placeholder === "Gender") {
setUser({...user, gender: e.target.value});
}
console.log(e.target);
if(e.target.id === "file"){
if (e.target.files) {
const img = document.getElementById("img");
console.log(img);
img.src = URL.createObjectURL(e.target.files[0]);
}
}
}
return <div>
<div>Inputs</div>
<input placeholder='Username' value={user.username} className='field' type="text" onChange={handleChange} />
<input placeholder='Email' value={user.email} className='field' type="email" onChange={handleChange} />
<input placeholder='Password' value={user.password} className='field' type="password" onChange={handleChange} />
<input placeholder='Age' value={user.age} className='field' name='age' type="number" onChange={handleChange} />
<input placeholder='Gender' value={user.gender} className='field' name='gender' type="text" onChange={handleChange} />
<div>file (only accept photo)</div>
<input id="file" type="file" accept="image/*" onChange={handleChange}></input>
<div>User Object's props</div>
<div>user.username: {user.username}</div>
<div>user.email: {user.email}</div>
<div>user.password: {user.password}</div>
<div>user.age: {user.age}</div>
<div>user.gender: {user.gender}</div>
<br />
<div>image display</div>
<img id="img"></img>
</div>
}
</script>
<script type="text/babel">
ReactDOM.render(
<App></App>
, document.getElementById("root"));
</script>
import React,{ useState} from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react';
import axios from 'axios';
const Create = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
Here I am sending data to a mock api I created
const postData = () =>{
axios.post(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData`,{
firstName,
lastName,
checkbox
})
}
This is the method I created to reset the form but it does not work.
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
}
This is my form where on click i am calling resetForm function but it is not resetting it
is sending the data but not resetting the form.
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder='First Name' onChange={(e)=>setFirstName(e.target.value) } />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder='Last Name' onChange={(e)=>setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox id="c1" label='I agree to the Terms and Conditions' onChange={(e)=>setCheckBox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={resetForm}>Submit</Button>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Create;
Actually it will reset the form, the problem is you do not use Controlled Components to show the latest update value in UI
you should bind the value like this:
<input type="text" value={this.state.value} onChange={this.handleChange} />
You can refer the doc here:
https://reactjs.org/docs/forms.html
You can reset your form using the native form.reset() method.
const Create = () => {
const ref = React.useRef(null);
const resetForm = () => ref.current.reset();
return (
<div>
<Form ref={ref}>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder="First Name" onChange={(e) => setFirstName(e.target.value)} />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder="Last Name" onChange={(e) => setLastName(e.target.value)} />
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
<br></br>
<Button onClick={() => navigate(-1)}>Go Back</Button>
</div>
);
};
export default Create;
For that, you have to set value property in your input. Try this
const Create = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [checkbox, setCheckBox] = useState(false);
const postData = () => {
console.log(firstName, lastName, checkbox);
};
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
};
return (
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input
id="f1"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input
id="last1"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
checked={checkbox}
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
</div>
);
};
have that problem with resetting the values of the input fields in the form. and wanted to ask if somebody knows a better and way to do that instead of just making 'useState' for every field...
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('sample_id', 'someother_id', formRef.current, 'user_is')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
setMessage(true);
setEmail("");
setName("");
setSubject("");
setTextarea("");
};
return (
<div className="contact" id="contact">
<div className="left">
<img src="" alt="" />
</div>
<div className="right">
<h2>Kontakt</h2>
<form ref={formRef} onSubmit={handleSubmit}>
<label>Name</label>
<input onChange={(e) => setName(e.target.value)} type="text" placeholder="Name" name="user_name" value={name} />
<label>Email</label>
<input onChange={(e) => setEmail(e.target.value)} type="email" placeholder="Email" name="user_email" value={email} />
<label>Betreff</label>
<input onChange={(e) => setSubject(e.target.value)} type="text" placeholder="Subject" name="user_subject" value={subject} />
<label>Nachricht</label>
<textarea onChange={(e) => setTextarea(e.target.value)} placeholder="Message" name="message" value={textarea} />
<button type="submit">Send</button>
{message && <span>Thanks we will respond ASAP.</span>}
</form>
</div>
</div>
)
}
You could use a single state for all the form values (kinda like we did before functional components)
// this could be outside your component
const initialState = { email: "", name: "", subject: "", textArea: ""};
// declaring your state
const [formState, setFormState] = React.useState(initialState);
and then
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm('sample_id', 'someother_id', formRef.current, 'user_is')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
setMessage(true);
setFormState(initialState)
};
You also would have to rewrite your input handlers. Like that :
<input onChange={(e) => setFormState({...formState, name: e.target.value})} type="text" placeholder="Name" name="user_name" value={name} />
i want to validate my form by checking if all the fields are filled. I am quite new to react. Any suggestions? I have got the states ready, but i am pretty much stuck. Thank you in advance for your replies. I appreciate it
my code:
const [fields, setFields] = useState({
name: '',
email: '',
subject: '',
msg: '',
});
const handleSubmit = (event) => {
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
alert('form submitted');
event.target.reset();
event.preventDefault();
};
<form onSubmit={handleSubmit}>
<div className={styles.firstInputs}>
<div>
<label>name</label>
<br />
<input
type='text'
refs='name'
name='name'
placeholder='your name'
></input>
</div>
<div>
<label>email</label>
<br />
<input type='email' name='email' placeholder='email'></input>
</div>
</div>
<label>subject</label>
<br />
<input
type='text'
name='subject'
placeholder='subject'
className={styles.subject}
></input>{' '}
<br />
<label>message</label> <br />
<textarea placeholder='your message' name='message'></textarea>
<br />
<button type='submit' className={styles.sendForm}>
SUBMIT
</button>
</form>;
You are not using your state correctly there.
Set the values of the fields to what is in the state, then change the state when the fields change.
Don't forget you can just add the required attribute to your HTML element to make sure it gets some kind of value.
Then you just validate the state before submission.
Don't just fall back on packages all the time as people suggest here. As you say, you are new to React so, learn to set things up manually (which is basically less work for small forms). Once you understand that, then consider if having another dependency is really saving you time.
See sample code below in action here: https://codesandbox.io/s/form-validation-pbbf1
import { useState } from "react";
import "./styles.css";
const defaultFields = { name: "", email: "", subject: "", message: "" };
export default function App() {
const [fields, setFields] = useState(defaultFields);
const handleSubmit = (event) => {
// Stop form from resetting
event.preventDefault();
// Check fields
if (fields.name.length < 2) {
return alert("Name should be greater than 1 character.");
}
// etc...
// Send off data
/*
emailjs.sendForm().then(
(result) => {
console.log(result.text);
},
(error) => {
console.log(error.text);
}
);
*/
// I would probably put these two
// lines inside the then block above.
setFields(defaultFields);
alert("form submitted");
};
const handleFieldChange = (e) => {
const { name, value } = e.target;
setFields((previousFields) => ({ ...previousFields, [name]: value }));
};
return (
<form onSubmit={handleSubmit}>
{/* NAME */}
<div>
<label>name</label>
<br />
<input
type="text"
name="name"
placeholder="your name"
value={fields.name}
required
onChange={handleFieldChange}
></input>
</div>
{/* EMAIL */}
<div>
<label>email</label>
<br />
<input
type="email"
name="email"
placeholder="email"
value={fields.email}
required
onChange={handleFieldChange}
></input>
</div>
{/* SUBJECT */}
<div>
<label>subject</label>
<br />
<input
type="text"
name="subject"
placeholder="subject"
value={fields.subject}
required
onChange={handleFieldChange}
></input>{" "}
<br />
</div>
{/* MESSAGE */}
<div>
<label>message</label> <br />
<textarea
placeholder="your message"
name="message"
value={fields.message}
required
onChange={handleFieldChange}
></textarea>
</div>
<button type="submit">SUBMIT</button>
</form>
);
}