在 ReactJS 中获取表单数据

IT技术 javascript html reactjs frontend
2021-01-22 07:49:47

我的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字段中写什么

6个回答

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

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>
    )
  }
}
@Madacol 这可能发生是你有几个同名的输入
2021-03-19 07:49:47
选项2对我不起作用。没有属性“元素”或“用户名”,即使我输入的名称是“用户名”
2021-03-21 07:49:47
选项 2 是最佳答案。getElementById如果您已经拥有event参数,通过获取元素是多余的
2021-03-27 07:49:47

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

工作小提琴

另外,阅读文档,有一整节专门用于表单处理:表单

以前你也可以使用 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>
    );
  }
});

文档在这里:双向绑定助手

看起来 valueLink 已被弃用
2021-03-13 07:49:47
这不是一直在客户端以明文形式存储密码吗?这似乎并不适合密码字段。
2021-03-19 07:49:47
您还可以在表单中使用 onSubmit 而不是带有按钮的 onClick
2021-04-06 07:49:47
为什么要为表单的每个元素使用一个状态?其他人认为这是一个不好的模式?
2021-04-08 07:49:47
为了正确模拟 的功能valueLink,您的第一个示例应该设置value输入元素的 。没有它,在 React 术语中,这些值是“不受控制的”<input ... value={this.state.password}>.
2021-04-09 07:49:47

另一种方法是使用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

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

实际上你不需要 React.findDOMNode this.refs.theInput 已经是一个 html 节点
2021-03-14 07:49:47
这个解决方案是否真的更好并且在提问时间不可用,或者它是一种“丑陋”的方式?
2021-03-15 07:49:47
refs 已贬值,此答案不再成立。
2021-03-28 07:49:47

添加 Michael Schock 的回答:

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

请参阅这篇 Medium 文章:如何使用 Just React 处理表单

此方法仅在按下提交按钮时获取表单数据。更清洁的海事组织!

这也可以防止在连续状态更改时重新渲染表单!
2021-03-22 07:49:47

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

如果您使用的是 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>
  );
};
很好的答案,但是挑剔你能不能删除 var 否则完美的解决方案!
2021-03-16 07:49:47
@tejasvi88 您需要调用 FormData 对象上的条目。并非所有 JS 对象都会在记录时显示其内容。
2021-03-19 07:49:47
任何人都可以帮助我使用上面这段代码片段的typescript变体吗?
2021-04-02 07:49:47
new FormData(event.target){}
2021-04-02 07:49:47
@Joseph 我的表单实际上没有名称属性。
2021-04-04 07:49:47