在Reactjs中获取表单数据

时间:2014-05-02 11:45:06

标签: javascript frontend 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() { ... }中撰写哪些内容才能访问EmailPassword字段?

23 个答案:

答案 0 :(得分:134)

使用输入上的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的双向数据绑定帮助mixin来实现同样的目的,但是现在不赞成设置值和更改处理程序(如上所述):

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 :(得分:87)

有几种方法可以做到这一点:

1)按索引

从表单元素数组中获取值
handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target[0].value)
}

2)在html中使用 name 属性

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

答案 2 :(得分:41)

另一种方法是使用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#the-ref-string-attribute

由于How do I use radio buttons in React?中描述的很多原因,这种方法并不总是最好的,但它确实在一些简单的情况下提供了一个有用的替代方案。

答案 3 :(得分:21)

对于那些不想使用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>)
        }

答案 4 :(得分:17)

处理裁判的简单方法:

&#13;
&#13;
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;
&#13;
&#13;
&#13;

答案 5 :(得分:10)

我建议采用以下方法:

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

}

答案 6 :(得分:10)

您可以将按钮上的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
}

答案 7 :(得分:9)

如果所有输入/文本区域均具有名称,则可以从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方法,值,defaultValue ...

答案 8 :(得分:4)

此外,这也可以使用。

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

答案 9 :(得分:4)

提供您的输入参考

ListAndCreateResource

然后您可以在soo中以登录方式访问它

response = ListAndCreateResource().as_view()(request._request, *args, **kwargs)

答案 10 :(得分:3)

 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>

Output image attached here

答案 11 :(得分:3)

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

答案 12 :(得分:3)

如果您在项目中使用Redux,则可以考虑使用此更高阶的组件https://github.com/erikras/redux-form

答案 13 :(得分:1)

使用es6 destructing

的更清晰示例
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>
        );
    }
}

答案 14 :(得分:1)

这可能有助于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 );
}

答案 15 :(得分:0)

改善用户体验;当用户点击提交按钮时,您可以尝试让表单首先显示发送消息。一旦我们收到服务器的响应,它就可以相应地更新消息。我们通过链接状态在React中实现了这一点。请参阅下面的codepen或摘要:

以下方法进行第一次状态更改:

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 ( ...

codepen

答案 16 :(得分:0)

如果元素名称多次出现,则必须使用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()是列表类的内置方法。您将无法在此处使用map()或reduce()。

答案 17 :(得分:0)

我这样使用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})
}`

答案 18 :(得分:0)

添加迈克尔·肖克的答案:

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

See this Medium article: How to Handle Forms with Just React

仅当按下Submit按钮时,此方法才获取表单数据。 IMO干净得多!

答案 19 :(得分:0)

我认为这也是您需要的答案。另外,在这里我添加了必需的属性。每个输入组件的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
}

答案 20 :(得分:0)

这是动态添加字段的示例。此处,表单数据将使用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

答案 21 :(得分:0)

无需使用引用,您可以使用事件进行访问

from flask import Flask,jsonify
app = Flask(__name__)
@app.route('/<name>',methods=['GET'])
def index(name):
     return jsonify({'out' : "Hello"+  " "+str(name)})
if __name__ == '__main__':
    app.run(debug=True)

答案 22 :(得分:0)

这是从表单中获取数据的最短方法以及仅使用 FormData 避免 id 和 ref 的最佳方法

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