How would I rewrite the following code without using 'LinkedStateMixin'? Since I am upgrading to React 15.0 and this feature is deprecated.
reactMixin(LoginView.prototype, React.addons.LinkedStateMixin);
<div className='form-group'>
<input type='text'
className='form-control input-lg'
valueLink={this.linkState('email')}
placeholder='Email' />
</div>
<div className='form-group'>
<input type='password'
className='form-control input-lg'
valueLink={this.linkState('password')}
placeholder='Password' />
</div>
The above code is where it is being used and I am using Redux for managing state.
You could just manage the state yourself. Are you using babel/es6?
class MyForm extends React.Component {
state = {}
emailChanged = (e) => {
this.setState({ email: e.target.value });
}
passwordChanged = (e) => {
this.setState({ password: e.target.value });
}
render() {
const { email, password } = this.state;
return (
<form>
<div className='form-group'>
<input type='text'
className='form-control input-lg'
value={email}
placeholder='Email'
onChange={this.emailChanged} />
</div>
<div className='form-group'>
<input type='password'
className='form-control input-lg'
value={password}
placeholder='Password'
onChange={this.passwordChanged} />
</div>
</form>
);
}
}
Example: http://www.webpackbin.com/EJjZTnu4Z
If you look at the Two-Way Binding Helpers doc page, there's an example that shows how to do the same thing without using LinkedStateMixin.
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 created a login form and now I want to convert my input fields to re- usable component. I created separate common input.jsx file. This is input.jsx file's code.
import React from "react";
const Input = ({ name, label, value, onChange }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input
value={value}
onChange={onChange}
id={name}
name={name}
type="text"
className="form-control"
/>
</div>
);
};
export default Input;
and imported it to my loginForm.jsx. Here is my loginForm.jsx render method
handleChange = ({ currentTarget: input }) => {
const account = { ...this.state.account };
account[input.name] = input.value;
this.setState({ account });
};
render() {
const { account } = this.state;
return (
<div>
<h1>Login</h1>
<form onSubmit={this.handleSubmit}>
<Input
name="username"
value={account.username}
label="Username"
onChange={this.handleChange}
/>
<Input
name="password"
value={account.password}
label="Password"
onChange={this.handleChange}
/>
<button className="btn btn-primary">Login</button>
</form>
</div>
);
}
But after adding below code to my loginForm.jsx,
<Input
name="username"
value={account.username}
label="Username"
onChange={this.handleChange}
/>
code and deleted previous code ,
<div className="form-group">
<label htmlFor="username">Username</label>
<input
value={account.username}
name="username"
onChange={this.handleChange}
ref={this.username}
id="username"
type="text"
className="form-control"
/>
</div>
suddenly my login page not loading.(Empty page).
My login page's console showing below error.
The above error occurred in the <LoginForm> component:
at LoginForm (http://localhost:3000/main.5d4e82bfe117bc198b43.hot-update.js:27:5)
at Route (http://localhost:3000/static/js/bundle.js:54444:5)
at Switch (http://localhost:3000/static/js/bundle.js:54739:5)
at main
at App
at Router (http://localhost:3000/static/js/bundle.js:54612:5)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:53870:5)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
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>
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>
);
}
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;