在Reactjs中获取表单数据

myu*_*suf 166 html 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 ?
}
Run Code Online (Sandbox Code Playgroud)

我应该在handleLogin: function() { ... }访问EmailPassword字段中写什么?

jba*_*ter 146

使用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);
}
Run Code Online (Sandbox Code Playgroud)

工作小提琴: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>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

文档在这里:http://facebook.github.io/react/docs/two-way-binding-helpers.html

  • 为什么对表单的每个元素使用状态?其他人都认为这是一个糟糕的模式? (39认同)
  • 您还可以使用带有表单的onSubmit而不是onClick与按钮 (9认同)
  • 看起来不推荐使用valueLink (5认同)
  • 为了正确地模仿valueLink的功能,您的第一个示例应该设置输入元素的value。否则,这些值将成为React术语中的[“ un受控”](https://facebook.github.io/react/docs/forms.html#un受控组件)。&lt;input ... value = {this.state.password}&gt;。 (2认同)
  • 这不是一直在客户端以明文形式存储密码吗?这似乎不适合密码字段. (2认同)
  • 这种方法的缺点是每次输入值变化时都会导致状态变化。如果您只需要用户提交表单时的值,则不应采用此方法。 (2认同)

Ali*_*ich 121

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

1)通过索引从表单元素数组中获取值

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target[0].value)
}
Run Code Online (Sandbox Code Playgroud)

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"/>
Run Code Online (Sandbox Code Playgroud)

3)使用refs

handleSubmit = (event) => {
  console.log(this.inputNode.value)
}

<input type="text" name="username" ref={node => (this.inputNode = node)}/>
Run Code Online (Sandbox Code Playgroud)

完整的例子

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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 选项 **2** 对我不起作用。即使我输入的名称是“用户名”,也没有属性“元素”或“用户名” (5认同)
  • @Madacol,如果您有一些同名的输入,则可能会发生这种情况 (2认同)
  • @Madacol,尝试使用“event.target.form.username.value”。这对我有用。 (2认同)

Jam*_*son 42

另一种方法是使用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);
}
Run Code Online (Sandbox Code Playgroud)

更多信息可以在React文档中找到:https: //facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute

由于如何在React中使用单选按钮中描述的很多原因这种方法并不总是最好的,但它确实在一些简单的情况下提供了一种有用的替代方法.

  • 实际上你不需要React.findDOMNode this.refs.theInput已经是一个html节点 (4认同)

Clo*_*ave 36

对于那些不想使用 ref 并使用OnChange事件重置状态的人,您可以使用简单的 OnSubmit 句柄并循环遍历FormData对象。

请注意,您无法formData.entries()直接访问,因为它是可迭代的,您必须对其进行循环。

这个例子使用的是 React Hooks:

const LoginPage = () => {
  const handleSubmit = (event) => {
    const formData = new FormData(event.currentTarget);
    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>
  );
};
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 TypeScript:

export const LoginPage: React.FC<{}> = () => {
  const handleSubmit: React.FormEventHandler<HTMLFormElement> = (event) => {
    const formData = new FormData(event.currentTarget);
    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>
  );
};
Run Code Online (Sandbox Code Playgroud)


Sam*_*a K 24

无需使用 refs,您可以使用事件访问

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>
Run Code Online (Sandbox Code Playgroud)

  • Great Sameera - 这很容易理解,来自 vanilla js。谢谢 (2认同)

E. *_*tes 21

处理refs的简单方法:

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;
Run Code Online (Sandbox Code Playgroud)

  • 这种方法将来某一天会被弃用.Refs仅用于回调而不是字符串.有关详细信息,请访问:https://facebook.github.io/react/docs/refs-and-the-dom.html (2认同)

Mic*_*ock 13

您可以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>
      );
    },
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用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
}
Run Code Online (Sandbox Code Playgroud)


小智 12

以下是从表单获取数据的最短方法,以及仅使用 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
Run Code Online (Sandbox Code Playgroud)


Ara*_*oca 11

如果您的所有输入/ textarea都有一个名称,那么您可以从event.target中过滤掉所有内容:

onSubmit(event){
  const fields = Array.prototype.slice.call(event.target)
      .filter(el => el.name)
      .reduce((form, el) => ({
        ...form,
        [el.name]: el.value,
      }), {})
}
Run Code Online (Sandbox Code Playgroud)

没有onChange方法,值,defaultValue的完全不受控制的形式......


Jam*_*wuh 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>
        )
    }

}
Run Code Online (Sandbox Code Playgroud)


hoo*_*o-b 7

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

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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

参见这篇中篇文章:如何使用Just React处理表单

仅当按下“提交”按钮时,此方法才获取表单数据。清洁得多的IMO!

  • 这也防止了在连续状态变化时重新渲染表单! (2认同)

Ser*_*zzo 6

更清晰的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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)


MA *_*man 6

对于 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>
Run Code Online (Sandbox Code Playgroud)


Ibr*_*m.B 6

如果您尝试Aliaksandr Sushkevich 的解决方案,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"/>
...
Run Code Online (Sandbox Code Playgroud)

不过,这仍然只是一种解决方法,因为在这里您正在告诉 TypeScript 会发生什么。如果您添加没有相应输入元素的值,这将在运行时中断。


小智 5

同样,这也可以使用。

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 请说明为什么此答案是正确的方法。 (4认同)

Imr*_*que 5

像这样给你的输入参考

<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />
Run Code Online (Sandbox Code Playgroud)

然后你可以像 soo 一样在你的 handleLogin 中访问它

handleLogin: function(e) {
   e.preventDefault();
    console.log(this.refs.email.value)
    console.log(this.refs.password.value)
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我这样使用 React 组件状态:

<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />

handleChange(e){
   this.setState({[e.target.name]: e.target.value})
}`
Run Code Online (Sandbox Code Playgroud)