Получить данные формы в Reactjs
У меня есть простая форма в моем render
функция, вот так:
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
//How to access email and password here ?
}
Что я должен написать в моем handleLogin: function() { ... }
чтобы получить доступ Email
а также Password
поля?
32 ответа
Использовать change
события на входах для обновления состояния компонента и доступа к нему в handleLogin
:
handleEmailChange: function(e) {
this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>);
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
}
Рабочая скрипка: http://jsfiddle.net/kTu3a/
Кроме того, прочитайте документы, есть целый раздел, посвященный обработке форм: http://facebook.github.io/react/docs/forms.html
Раньше вы могли также использовать двусторонний вспомогательный миксин привязки данных React для достижения того же результата, но теперь он устарел в пользу установки значения и изменения обработчика (как указано выше):
var ExampleForm = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {email: '', password: ''};
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
},
render: function() {
return (
<form>
<input type="text" valueLink={this.linkState('email')} />
<input type="password" valueLink={this.linkState('password')} />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
}
});
Документация находится здесь: http://facebook.github.io/react/docs/two-way-binding-helpers.html
Есть несколько способов сделать это:
1) Получить значения из массива элементов формы по индексу
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target[0].value)
}
2) Использование атрибута имени в HTML
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target.elements.username.value) // from elements property
console.log(event.target.username.value) // or directly
}
<input type="text" name="username"/>
3) Использование ссылок
handleSubmit = (event) => {
console.log(this.inputNode.value)
}
<input type="text" name="username" ref={node => (this.inputNode = node)}/>
Полный пример
class NameForm extends React.Component {
handleSubmit = (event) => {
event.preventDefault()
console.log(event.target[0].value)
console.log(event.target.elements.username.value)
console.log(event.target.username.value)
console.log(this.inputNode.value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
name="username"
ref={node => (this.inputNode = node)}
/>
</label>
<button type="submit">Submit</button>
</form>
)
}
}
Добавляем к ответу Майкла Шока:
class MyForm extends React.Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
const data = new FormData(event.target);
console.log(data.get('email')); // reference by form input's `name` tag
fetch('/api/form-submit-url', {
method: 'POST',
body: data,
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="username">Enter username</label>
<input id="username" name="username" type="text" />
<label htmlFor="email">Enter your email</label>
<input id="email" name="email" type="email" />
<label htmlFor="birthdate">Enter your birth date</label>
<input id="birthdate" name="birthdate" type="text" />
<button>Send data!</button>
</form>
);
}
}
Посмотрите эту среднюю статью: Как обрабатывать формы с помощью Just React
Этот метод получает данные формы только при нажатии кнопки "Отправить". Гораздо чище ИМО!
Для тех, кто не хочет использовать ref и сбрасывать состояние с помощью OnChange
вы можете просто использовать простой дескриптор OnSubmit и пройти через FormData
объект. В этом примере используются React Hooks:
const LoginPage = () =>{
const handleSubmit = (event) => {
const formData = new FormData(event.target);
event.preventDefault();
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
}
return (
<div>
<form onSubmit={
handleSubmit
}
>
<input type="text" name="username" placeholder="Email" />
<input type="password" name="password"
placeholder="Password" />
<button type="submit">Login</button>
</form>
</div>)
}
Не нужно использовать ссылки, вы можете получить доступ с помощью события
function handleSubmit(e) {
e.preventDefault()
const {username, password } = e.target.elements
console.log({username: username.value, password: password.value })
}
<form onSubmit={handleSubmit}>
<input type="text" id="username"/>
<input type="text" id="password"/>
<input type="submit" value="Login" />
</form>
Альтернативный подход заключается в использовании ref
атрибут и ссылки на значения с this.refs
, Вот простой пример:
render: function() {
return (<form onSubmit={this.submitForm}>
<input ref="theInput" />
</form>);
},
submitForm: function(e) {
e.preventDefault();
alert(React.findDOMNode(this.refs.theInput).value);
}
Дополнительную информацию можно найти в документации React: https://facebook.github.io/react/docs/more-about-refs.html.
По многим причинам, описанным в разделе Как использовать переключатели в React? этот подход не всегда лучший, но он представляет полезную альтернативу в некоторых простых случаях.
Простой способ справиться с реферами:
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const formData = {};
for (const field in this.refs) {
formData[field] = this.refs[field].value;
}
console.log('-->', formData);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input ref="phone" className="phone" type='tel' name="phone"/>
<input ref="email" className="email" type='tel' name="email"/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default UserInfo;
Вы могли бы переключить onClick
обработчик события на кнопке onSubmit
обработчик в форме:
render : function() {
return (
<form onSubmit={this.handleLogin}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
Тогда вы можете использовать FormData
проанализировать форму (и построить объект JSON из его записей, если хотите).
handleLogin: function(e) {
const formData = new FormData(e.target)
const user = {}
e.preventDefault()
for (let entry of formData.entries()) {
user[entry[0]] = entry[1]
}
// Do what you will with the user object here
}
Если у всех ваших входов / текстовой области есть имя, вы можете отфильтровать все из event.target:
onSubmit(event){
const fields = Array.prototype.slice.call(event.target)
.filter(el => el.name)
.reduce((form, el) => ({
...form,
[el.name]: el.value,
}), {})
}
Полностью неконтролируемая форма без методов onChange, value, defaultValue...
Я бы предложил следующий подход:
import {Autobind} from 'es-decorators';
export class Form extends Component {
@Autobind
handleChange(e) {
this.setState({[e.target.name]: e.target.value});
}
@Autobind
add(e) {
e.preventDefault();
this.collection.add(this.state);
this.refs.form.reset();
}
shouldComponentUpdate() {
return false;
}
render() {
return (
<form onSubmit={this.add} ref="form">
<input type="text" name="desination" onChange={this.handleChange}/>
<input type="date" name="startDate" onChange={this.handleChange}/>
<input type="date" name="endDate" onChange={this.handleChange}/>
<textarea name="description" onChange={this.handleChange}/>
<button type="submit">Add</button>
</form>
)
}
}
Вот самый короткий способ получить данные из формы и лучший способ избежать идентификатора и ссылки, просто используя FormData
import React, { Component } from 'react'
class FormComponent extends Component {
formSubmit = (event) => {
event.preventDefault()
var data = new FormData(event.target)
let formObject = Object.fromEntries(data.entries())
console.log(formObject)
}
render() {
return (
<div>
<form onSubmit={this.formSubmit}>
<label>Name</label>
<input name="name" placeholder="name" />
<label>Email</label>
<input type="email" name="email" />
<input type="submit" />
</form>
</div>
)
}
}
export default FormComponent
Для пользователей TypeScript
import react from 'react'
interface FormInterface {
[key: string]: string
}
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
let formData = new FormData(event.currentTarget)
let formObj: FormInterface = {}
for (let [key, value] of Array.from(formData.entries())) {
formObj[key] = value.toString()
}
};
<form onSubmit={handleSubmit}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
TypeScript будет жаловаться, если вы попробуете решение Александра Сушкевича . Один обходной путь можно сделать с помощью утверждений типа:
<form
onSubmit={(e: React.SyntheticEvent) => {
e.preventDefault();
const target = e.target as typeof e.target & {
username: { value: string };
password: { value: string };
};
const username = target.username.value; // typechecks
const password = target.password.value; // typechecks
// etc...
}}
>
<input type="text" name="username"/>
...
Тем не менее, это всего лишь обходной путь, потому что здесь вы говорите TypeScript, чего ожидать. Это сломается во время выполнения, если вы добавите значение, у которого нет соответствующего элемента ввода.
Более наглядный пример с разрушением es6
class Form extends Component {
constructor(props) {
super(props);
this.state = {
login: null,
password: null,
email: null
}
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
let login = this.state.login;
let password = this.state.password;
// etc
}
render() {
return (
<form onSubmit={this.onSubmit.bind(this)}>
<input type="text" name="login" onChange={this.onChange.bind(this)} />
<input type="password" name="password" onChange={this.onChange.bind(this)} />
<input type="email" name="email" onChange={this.onChange.bind(this)} />
<button type="submit">Sign Up</button>
</form>
);
}
}
Дайте ваши ссылки, как это
<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />
тогда вы можете получить к нему доступ в своем дескрипторе, как Су
handleLogin: function(e) {
e.preventDefault();
console.log(this.refs.email.value)
console.log(this.refs.password.value)
}
Я использую так, используя состояние React Component:
<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />
handleChange(e){
this.setState({[e.target.name]: e.target.value})
}`
Кроме того, это может быть использовано тоже.
handleChange: function(state,e) {
this.setState({[state]: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
console.log("EMail: ", this.state.email);
console.log("Password: ", this.state.password);
}
Если вы используете Redux в своем проекте, вы можете рассмотреть возможность использования этого компонента более высокого порядка https://github.com/erikras/redux-form.
Во многих событиях в JavaScript мы имеем event
которые дают объект, включая то, что произошло событие и каковы значения, и т. д...
Это то, что мы используем с формами в ReactJs...
Итак, в вашем коде вы устанавливаете состояние на новое значение... примерно так:
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
}
handleLogin(e) {
e.preventDefault();
for (const field in this.refs) {
this.setState({this.refs[field]: this.refs[field].value});
}
}
render() {
return (
<div>
<form onSubmit={this.handleLogin}>
<input ref="email" type="text" name="email" placeholder="Email" />
<input ref="password" type="password" name="password" placeholder="Password" />
<button type="button">Login</button>
</form>
</div>
);
}
}
export default UserInfo;
Также это пример формы в React v.16, просто как ссылка на форму, которую вы создадите в будущем:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Это пример динамически добавляемого поля. Здесь данные формы будут храниться по ключу имени ввода с использованием хука React useState.
import React, { useState } from 'react'
function AuthForm({ firebase }) {
const [formData, setFormData] = useState({});
// On Form Submit
const onFormSubmit = (event) => {
event.preventDefault();
console.log('data', formData)
// Submit here
};
// get Data
const getData = (key) => {
return formData.hasOwnProperty(key) ? formData[key] : '';
};
// Set data
const setData = (key, value) => {
return setFormData({ ...formData, [key]: value });
};
console.log('firebase', firebase)
return (
<div className="wpcwv-authPage">
<form onSubmit={onFormSubmit} className="wpcwv-authForm">
<input name="name" type="text" className="wpcwv-input" placeholder="Your Name" value={getData('name')} onChange={(e) => setData('name', e.target.value)} />
<input name="email" type="email" className="wpcwv-input" placeholder="Your Email" value={getData('email')} onChange={(e) => setData('email', e.target.value)} />
<button type="submit" className="wpcwv-button wpcwv-buttonPrimary">Submit</button>
</form>
</div>
)
}
export default AuthForm
onChange(event){
console.log(event.target.value);
}
handleSubmit(event){
event.preventDefault();
const formData = {};
for (const data in this.refs) {
formData[data] = this.refs[data].value;
}
console.log(formData);
}
<form onSubmit={this.handleSubmit.bind(this)}>
<input type="text" ref="username" onChange={this.onChange} className="form-control"/>
<input type="text" ref="password" onChange={this.onChange} className="form-control"/>
<button type="submit" className="btn-danger btn-sm">Search</button>
</form>
Улучшить пользовательский опыт; когда пользователь нажимает на кнопку отправки, вы можете попытаться получить форму, чтобы сначала показать отправляющее сообщение. Получив ответ от сервера, он может соответствующим образом обновить сообщение. Мы достигаем этого в React путем объединения статусов. Смотри кодовый блок или фрагменты ниже:
Следующий метод выполняет первое изменение состояния:
handleSubmit(e) {
e.preventDefault();
this.setState({ message: 'Sending...' }, this.sendFormData);
}
Как только React отобразит вышеприведенное сообщение об отправке на экране, он вызовет метод, который отправит данные формы на сервер: this.sendFormData(). Для простоты я добавил setTimeout, чтобы имитировать это.
sendFormData() {
var formData = {
Title: this.refs.Title.value,
Author: this.refs.Author.value,
Genre: this.refs.Genre.value,
YearReleased: this.refs.YearReleased.value};
setTimeout(() => {
console.log(formData);
this.setState({ message: 'data sent!' });
}, 3000);
}
В React метод this.setState() отображает компонент с новыми свойствами. Таким образом, вы также можете добавить некоторую логику в метод render() компонента формы, который будет вести себя по-разному в зависимости от типа ответа, который мы получаем от сервера. Например:
render() {
if (this.state.responseType) {
var classString = 'alert alert-' + this.state.type;
var status = <div id="status" className={classString} ref="status">
{this.state.message}
</div>;
}
return ( ...
Это может помочь пользователям Meteor (v1.3):
render: function() {
return (
<form onSubmit={this.submitForm.bind(this)}>
<input type="text" ref="email" placeholder="Email" />
<input type="password" ref="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
submitForm: function(e) {
e.preventDefault();
console.log( this.refs.email.value );
console.log( this.refs.password.value );
}
Самое простое решение, которое пришло мне в голову, это:
<form onSubmit={(e) => handleLogin(e)}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
Функция вашей ручки:
const handleLogin = (e) => {
e.preventDefault()
const data = {
email: e.target.elements.email.value,
password: e.target.elements.password.value
}
console.log('FormData: ', data)
}
Когда вы нажмете кнопку входа в систему, вы увидите FormData в консоли в следующем формате:FormData: {email: 'whatever you tiped here', password: 'also whatever you tiped here'}
.
e.target.elements.email.value
нацелены на элементы с определенным именем, в вашем случае это адрес электронной почты и пароль.
Послеconsole.log
вhandleLogin
, вы можете выполнить некоторую логику проверки и логику входа.
const HandleSubmit = (e) => {
e.preventDefault();
let formData = e.target[0].form;
axios({
url: 'http://localhost:4000/data/add',
method: 'POST',
data: new FormData(formData)
}).then(async (data) => {
await toastr.success('Added Successfully', {
timeOut: 1000,
});
await setTimeout(() => {
window.location.reload();
}, 1000)
})
}
Если у вас есть несколько вхождений имени элемента, вы должны использовать forEach().
HTML
<input type="checkbox" name="delete" id="flizzit" />
<input type="checkbox" name="delete" id="floo" />
<input type="checkbox" name="delete" id="flum" />
<input type="submit" value="Save" onClick={evt => saveAction(evt)}></input>
JS
const submitAction = (evt) => {
evt.preventDefault();
const dels = evt.target.parentElement.delete;
const deleted = [];
dels.forEach((d) => { if (d.checked) deleted.push(d.id); });
window.alert(deleted.length);
};
Обратите внимание, что dels в этом случае является RadioNodeList, а не массивом, и не является Iterable. ForEach () является встроенным методом класса списка. Вы не сможете использовать карту () или уменьшить () здесь.
<form onSubmit={handleLogin}>
<input type="text" name="email" placeholder="Email" />
<input type="text" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
const handleLogin = (event) => {
event.preventDefault();
console.log(event.target[0].value)
console.log(event.target[1].value)
}
Если вы используете React 18, этот подход подойдет вам:
export default function Search() {
function search(e) {
e.preventDefault();
console.log("search clicked data = " + e.target[0].value);
}
return (
<form onSubmit={search}>
<input name="query" />
<button type="submit">Search</button>
</form>
);
}
официальная документация не работает, но вот ссылка на случай, если в будущем они это исправят: https://react.dev/reference/react-dom/comComponents/form#handle-form-submission-on-the-client
Думаю, это тоже ответ, который вам нужен. Кроме того, здесь я добавляю обязательные атрибуты. Атрибуты onChange каждого входного компонента являются функциями. Вам нужно добавить туда свою логику.
handleEmailChange: function(e) {
this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
formSubmit : async function(e) {
e.preventDefault();
// Form submit Logic
},
render : function() {
return (
<form onSubmit={(e) => this.formSubmit(e)}>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} required />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} required />
<button type="button">Login</button>
</form>);
},
handleLogin: function() {
//Login Function
}
Это будет самый простой способ
const formValidator = (form) => {
let returnData = {}
console.log(form.length);
for (let i = 0; i < form.length; i++) {
const data = form[i]
if (data.name != null && data.name != "") {
returnData[data.name] = data.value;
}
}
return returnData
}
По форме просто
<form onSubmit={(e) => {
e.preventDefault()
let data = formValidator(e.currentTarget)
}}>
<RoundTextFiled name='app-id' style={{ marginTop: '10px', borderRadius: '20px' }} label="App id" fullWidth required />
<RoundTextFiled name='api-hash' style={{ marginTop: '5px' }} label="Api hash" fullWidth required />
<RoundTextFiled name='channel-id' style={{ marginTop: '5px' }} label="Channel id" fullWidth required />
<Button type='submit' variant="contained" fullWidth style={{ padding: '10px', marginTop: '5px', borderRadius: '10px' }}>Login</Button>
</form>