Javascript 如何使用 ReactJS 获取输入字段的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36683770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:26:21  来源:igfitidea点击:

How to get the value of an input field using ReactJS?

javascriptreactjs

提问by JoeTidee

I have the following React component:

我有以下 React 组件:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        var title = this.title;
        console.log(title);
    }

    render(){
        return (
            ...
            <form className="form-horizontal">
                ...
                <input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" onClick={this.onSubmit} className="btn">Save</button>
            ...
        );
    }

};

The console is giving me undefined- any ideas what's wrong with this code?

控制台给了我undefined- 知道这段代码有什么问题吗?

采纳答案by Md. Maidul Islam

You should use constructor under the class MyComponent extends React.Component

你应该在类 MyComponent extends React.Component 下使用构造函数

constructor(props){
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }

Then you will get the result of title

然后你会得到标题的结果

回答by Mike 'Pomax' Kamermans

There are three answers here, depending on the version of React you're (forced to) work(ing) with, and whether you want to use hooks.

这里有三个答案,取决于你(被迫)使用的 React 版本,以及你是否想要使用钩子。

First things first:

第一件事:

It's important to understand how React works, so you can do things properly (protip: it's is superworth running through the React tutorial exercise on the React website. It's well written, and covers all the basics in a way that actually explains how to do things). "Properly" here means that you're writing an application interface that happens to be rendered in a browser; all the interface work happens in React, not in "what you're used to if you're writing a web page" (this is why React apps are "apps", not "web pages").

了解 React 的工作原理很重要,这样你才能正确地做事(提示:通过 React 网站上的 React 教程练习是非常值得的。它写得很好,并以一种实际解释如何做的方式涵盖了所有基础知识事物)。这里的“正确”意味着您正在编写一个恰好在浏览器中呈现的应用程序界面;所有的界面工作都发生在 React 中,而不是“你在编写网页时习惯的东西”(这就是为什么 React 应用程序是“应用程序”,而不是“网页”)。

React applications are rendered based off of two things:

React 应用程序的呈现基于两件事:

  1. the component's properties as declared by whichever parent creates an instance of that component, which the parent can modify throughout its lifecycle, and
  2. the component's own internal state, which it can modify itself throughout its own lifecycle.
  1. 由任何父级声明的组件属性创建该组件的实例,父级可以在其整个生命周期中修改该实例,以及
  2. 组件自己的内部状态,它可以在自己的整个生命周期中修改自己。

What you're expressly notdoing when you use React is generating HTML elements and then using those: when you tell React to use an <input>, for instance, you are notcreating an HTML input element, you are telling React to create a React input object that happens to renderas an HTML input element, and whose event handling looks at, but is not controlled by, the HTML element's input events.

当您使用 React 时,您明确没有做的是生成 HTML 元素然后使用这些元素:<input>例如,当您告诉 React 使用 an 时,您不是在创建 HTML 输入元素,而是告诉 React 创建一个 React 输入对象恰好呈现为 HTML 输入元素,其事件处理会查看HTML 元素的输入事件,但不受 控制

When using React, what you're doing is generating application UI elements that present the user with (often manipulable) data, with user interaction changing the Component's state, which maycause a rerender of part of your application interface to reflect the new state. In this model, the state is alwaysthe final authority, not "whatever UI library is used to render it", which on the web is the browser's DOM. The DOM is almost an afterthought in this programming model: it's just the particular UI framework that React happens to be using.

使用 React 时,您所做的是生成应用程序 UI 元素,向用户呈现(通常是可操作的)数据,用户交互会更改组件的状态,这可能会导致应用程序界面的一部分重新呈现以反映新状态。在这个模型中,状态始终是最终的权威,而不是“使用任何 UI 库来呈现它”,在网络上它是浏览器的 DOM。在这个编程模型中,DOM 几乎是事后的想法:它只是 React 碰巧使用的特定 UI 框架。

So in the case of an input element, the logic is:

所以在输入元素的情况下,逻辑是:

  1. You type in the input element,
  2. nothing happens to your input element yet, the event got intercepted by React and killed off immediately,
  3. React forwards the event to the function you've set up for event handling,
  4. that function mayschedule a state update,
  5. if it does, React runs that state update (asynchronously!) and will trigger a rendercall after the update, but only ifthe state update changedthe state.
  6. only afterthis render has taken place will the UI show that you "typed a letter".
  1. 你输入输入元素,
  2. 您的输入元素还没有发生任何事情,该事件被 React 拦截并立即终止
  3. React 将事件转发到您为事件处理设置的函数,
  4. 该函数可以安排状态更新,
  5. 如果是,React 运行状态更新(异步!)并render在更新后触发调用,但前提是状态更新改变了状态。
  6. 只有此渲染发生后,UI 才会显示您“键入了一个字母”。

All of that happens in a matter of milliseconds, if not less, so it lookslike you typed into the input element in the same way you're used to from "just using an input element on a page", but that's absolutely not what happened.

所有这一切都在几毫秒内发生,如果不是更短的话,所以看起来您以与“仅在页面上使用输入元素”相同的方式输入输入元素,但这绝对不是什么发生了。

So, with that said, on to how to get values from elements in React:

所以,话虽如此,关于如何从 React 中的元素获取值:

React 15 and below, with ES5

React 15 及以下,使用 ES5

To do things properly, your component has a state value, which is shown via an input field, and we can update it by making that UI element send change events back into the component:

为了正确地做事,你的组件有一个状态值,它通过输入字段显示,我们可以通过让 UI 元素将更改事件发送回组件来更新它:

var Component = React.createClass({
  getInitialState: function() {
    return {
      inputValue: ''
    };
  },

  render: function() {
    return (
      //...
      <input value={this.state.inputValue} onChange={this.updateInputValue}/>
      //...
    );
  },

  updateInputValue: function(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

So we tell React to use the updateInputValuefunction to handle the user interaction, use setStateto schedule the state update, and the fact that rendertaps into this.state.inputValuemeans that when it rerenders after updating the state, the user will see the update text based on what they typed.

所以我们告诉 React 使用该updateInputValue函数来处理用户交互,使用它setState来安排状态更新,事实上,rendertap intothis.state.inputValue意味着当它在更新状态后重新渲染时,用户将根据他们输入的内容看到更新文本。

addendum based on comments

基于评论的附录

Given that UI inputs represent state values (consider what happens if a user closes their tab midway, and the tab is restored. Should all those values they filled in be restored? If so, that's state). That might make you feel like a large form needs tens or even a hundred input forms, but React is about modeling your UI in a maintainable way: you do not have 100 independent input fields, you have groups of related inputs, so you capture each group in a component and then build up your "master" form as a collection of groups.

鉴于 UI 输入表示状态值(考虑如果用户中途关闭他们的选项卡会发生什么,并且选项卡被恢复。他们填写的所有这些值是否应该被恢复?如果是,那就是状态)。这可能会让你觉得一个大表单需要几十个甚至一百个输入表单,但 React 是以可维护的方式建模你的 UI:你没有 100 个独立的输入字段,你有一组相关的输入,所以你捕获每个在一个组件中分组,然后将您的“主”表单构建为一组组。

MyForm:
  render:
    <PersonalData/>
    <AppPreferences/>
    <ThirdParty/>
     ...

This is also much easier to maintain than a giant single form component. Split up groups into Components with state maintenance, where each component is only responsible for tracking a few input fields at a time.

这也比一个巨大的单一表单组件更容易维护。将组拆分为具有状态维护的组件,其中每个组件一次仅负责跟踪几个输入字段。

You may also feel like it's "a hassle" to write out all that code, but that's a false saving: developers-who-are-not-you, including future you, actually benefit greatly from seeing all those inputs hooked up explicitly, because it makes code paths much easier to trace. However, you can always optimize. For instance, you can write a state linker

您可能还会觉得写出所有这些代码“很麻烦”,但这是一种错误的节省:不是您的开发人员,包括未来的您,实际上从看到所有这些输入显式连接中受益匪浅,因为它使代码路径更容易跟踪。但是,您始终可以优化。例如,您可以编写一个状态链接器

MyComponent = React.createClass({
  getInitialState() {
    return {
      firstName: this.props.firstName || "",
      lastName: this.props.lastName || "" 
      ...: ...
      ...
    }
  },
  componentWillMount() {
    Object.keys(this.state).forEach(n => {
      let fn = n + 'Changed';
      this[fn] = evt => {
        let update = {};
        update[n] = evt.target.value;
        this.setState(update);
      });
    });
  },
  render: function() {
    return Object.keys(this.state).map(n => {
      <input
        key={n} 
        type="text"
        value={this.state[n]}
        onChange={this[n + 'Changed']}/>
    });
  }
});

Of course, there are improved versions of this, so hit up https://npmjs.comand search for a React state linking solution that you like best. Open Source is mostly about finding what others have already done, and using that instead of writing everything yourself from scratch.

当然,还有改进的版本,因此请访问 https://npmjs.com并搜索您最喜欢的 React 状态链接解决方案。开源主要是寻找其他人已经完成的工作,并使用它而不是自己从头开始编写所有内容。

React 16 (and 15.5 transitional) and 'modern' JS

React 16(和 15.5 过渡版)和“现代”JS

As of React 16 (and soft-starting with 15.5) the createClasscall is no longer supported, and class syntax needs to be used. This changes two things: the obvious class syntax, but also the thiscontext binding that createClasscan do "for free", so to ensure things still work make sure you're using "fat arrow" notation for thiscontext preserving anonymous functions in onWhateverhandlers, such as the onChangewe use in the code here:

从 React 16(和 15.5 软启动)开始,createClass不再支持调用,需要使用类语法。这改变了两件事:明显的类语法,还有可以“免费”执行的this上下文绑定createClass,因此为了确保事情仍然有效,请确保您使用“粗箭头”表示法thisonWhatever处理程序中保留匿名函数的上下文,例如在onChange这里的代码中,我们使用:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      //...
      <input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
      //...
    );
  },

  updateInputValue(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

You may also have seen people use bindin their constructor for all their event handling functions, like this:

您可能还看到人们bind在其构造函数中使用所有事件处理函数,如下所示:

constructor(props) {
  super(props);
  this.handler = this.handler.bind(this);
  ...
}

render() {
  return (
    ...
    <element onclick={this.handler}/>
    ...
  );
}

Don't do that.

不要那样做。

Almost any time you're using bind, the proverbial "you're doing it wrong" applies. Your class already defines the prototype, and so as programming model already defines the instance context. Don't put bindof top of that an use normal event forwarding instead of duplicating all your function calls in the constructor. Now you've increased your bug surface, and made it much harder to trace errors because the problem might be in your constructor instead of where you call your code. In addition of placing a burden of maintenance on others you (have or choose) to work with.

几乎在您使用 的任何时候bind,谚语“您做错了”都适用。您的类已经定义了原型,因此编程模型已经定义了实例上下文。不要bind在此之上使用普通事件转发,而不是在构造函数中复制所有函数调用。现在您已经增加了您的错误面,并使跟踪错误变得更加困难,因为问题可能出在您的构造函数中,而不是您调用代码的位置。除了将维护负担置于您(必须或选择)与之合作的其他人之外。

Yes, I know the react docs say it's fine. It's not, don't do it.

是的,我知道反应文档说这很好。不是,不要这样做。

React 16.8, using function components with hooks

React 16.8,使用带有钩子的函数组件

As of React 16.8 the function component (i.e. literally just a function that takes some propsas argument can be used as if it's an instance of a component class, without ever writing a class) can also be given state, through the use of hooks.

从 React 16.8 开始,函数组件(即实际上只是一个将 someprops作为参数的函数可以像组件类的实例一样使用,而无需编写类)也可以通过使用hooks来获得状态。

If you don't need full class code, and a single instance function will do, then you can now use the useStatehook to get yourself a single state variable, and its update function, which works roughly the same as the above examples, except without the setStatefunction call:

如果您不需要完整的类代码,而单个实例函数就可以,那么您现在可以使用useState钩子为自己获取单个状态变量及其更新函数,其工作原理与上述示例大致相同,只是没有该setState函数调用:

import { useState } from 'react';

function myFunctionalComponentFunction() {
  const [input, setInput] = useState(''); // '' is the initial state value
  return (
    <div>
    <label>Please specify:</label>
    <input value={input} onInput={e => setInput(e.target.value)}/>
    </div>
  );
}

Previously the unofficial distinction between classes and function components was "function components don't have state", so we can't hide behind that one anymore: the difference between function components and classes components can be found spread over several pages in the very well-written react documentation(no shortcut one liner explanation to conveniently misinterpret for you!) which you should read so that you know what you're doing and can thus know whether you picked the best (whatever that means for you) solution to program yourself out of a problem you're having.

以前类和函数组件之间的非官方区别是“函数组件没有状态”,所以我们不能再躲在那个后面:函数组件和类组件之间的区别可以在很好的几页中找到- 编写的反应文档(没有捷径可以方便地误解你!)你应该阅读它,这样你就知道你在做什么,从而知道你是否选择了最好的(无论对你来说意味着什么)解决方案来编程自己出于您遇到的问题。

回答by Hugo Wesley

Managed to get the input field value by doing something like this:

通过执行以下操作设法获取输入字段值:

import React, { Component } from 'react';

class App extends Component {

constructor(props){
super(props);

this.state = {
  username : ''
}

this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}


updateInput(event){
this.setState({username : event.target.value})
}


handleSubmit(){
console.log('Your input value is: ' + this.state.username)
//Send state to the server code
}



render(){
return (
    <div>
    <input type="text" onChange={this.updateInput}></input>
    <input type="submit" onClick={this.handleSubmit} ></input>
    </div>
  );
}
} 

//output
//Your input value is: x

回答by Pyae Sone

In react 16, I use

在反应 16 中,我使用

<Input id="number" 
       type="time" 
       onChange={(evt) => { console.log(evt.target.value); }} />

回答by Matthias Liszt

I succeeded in doing this by binding the "this" to the function updateInputValue(evt) with

我通过将“this”绑定到函数 updateInputValue(evt) 成功地做到了这一点

this.updateInputValue = this.updateInputValue.bind(this);

this.updateInputValue = this.updateInputValue.bind(this);

However input value={this.state.inputValue} ... turned out to be no good idea.

然而 input value={this.state.inputValue} ... 原来不是一个好主意。

Here's the full code in babel ES6 :

这是 babel ES6 中的完整代码:

class InputField extends React.Component{


  constructor(props){
   super(props);
   //this.state={inputfield: "no value"};   
   this.handleClick = this.handleClick.bind(this);
   this.updateInputValue = this.updateInputValue.bind(this);
  }

  handleClick(){
   console.log("trying to add picture url");
   console.log("value of input field : "+this.state.inputfield);

  }

  updateInputValue(evt){
    //console.log("input field updated with "+evt.target.value);
    this.state={inputfield: evt.target.value};   

  }

  render(){
    var r; 
    r=<div><input type="text" id="addpixinputfield" 
            onChange={this.updateInputValue} />
      <input type="button" value="add" id="addpix" onClick={this.handleClick}/>
      </div>;    
    return r;
   }
}

回答by Soroush Bk

your error is because of you use class and when use class we need to bind the functions with This in order to work well. anyway there are a lot of tutorial why we should "this" and what is "this" do in javascript.

你的错误是因为你使用了类,当使用类时,我们需要将函数与 This 绑定才能正常工作。无论如何,有很多教程为什么我们应该“这个”以及“这个”在javascript中做什么。

if you correct your submit button it should be work:

如果您更正提交按钮,它应该可以工作:

<button type="button" onClick={this.onSubmit.bind(this)} className="btn">Save</button>

and also if you want to show value of that input in console you should use var title = this.title.value;

此外,如果您想在控制台中显示该输入的值,您应该使用 var title = this.title.value;

回答by Kidali Kevin

// On the state
constructor() {
  this.state = {
   email: ''
 }
}

// Input view ( always check if property is available in state {this.state.email ? this.state.email : ''}

<Input 
  value={this.state.email ? this.state.email : ''} 
  onChange={event => this.setState({ email: event.target.value)}
  type="text" 
  name="emailAddress" 
  placeholder="[email protected]" />

回答by Katarzyna Wrońska

Change your ref into: ref='title'and delete name='title'Then delete var title = this.titleand write:

将您的 ref 更改为:ref='title'并删除name='title'然后删除var title = this.title并写入:

console.log(this.refs.title.value)

Also you should add .bind(this)to this.onSubmit

你也应该添加.bind(this)this.onSubmit

(It worked in my case which was quite similar, but instead of onClickI had onSubmit={...}and it was put in form ( <form onSubmit={...} ></form>))

(它在我的情况下非常相似,但不是onClick我有onSubmit={...},而是以 ( <form onSubmit={...} ></form>))

回答by Lord

if you use class component then only 3 steps- first you need to declare state for your input filed for example this.state = {name:''}. Secondly, you need to write a function for setting the state when it changes in bellow example it is setName()and finally you have to write the input jsx for example < input value={this.name} onChange = {this.setName}/>

如果您使用类组件,则只需 3 个步骤 - 首先您需要为您的输入声明状态,例如this.state = {name:''}。其次,您需要编写一个用于设置状态的函数,在下面的示例中它是setName(),最后您必须编写输入 jsx 例如 < input value={this.name} onChange = {this.setName} />

import React, { Component } from 'react'

export class InputComponents extends Component {
    constructor(props) {
        super(props)

        this.state = {
             name:'',
             agree:false
        }
        this.setName = this.setName.bind(this);
        this.setAgree=this.setAgree.bind(this);
    }

    setName(e){
        e.preventDefault();
        console.log(e.target.value);
        this.setState({
            name:e.target.value
        })
    }
    setAgree(){
        this.setState({
            agree: !this.state.agree
        }, function (){
            console.log(this.state.agree);
        })
    }
    render() {
        return (
            <div>
                <input type="checkbox" checked={this.state.agree} onChange={this.setAgree}></input>
                < input value={this.state.name} onChange = {this.setName}/>
            </div>
        )
    }
}

export default InputComponents

回答by Pranav Agarwal

export default class MyComponent extends React.Component {

onSubmit(e) {
    e.preventDefault();
    var title = this.title.value; //added .value
    console.log(title);
}

render(){
    return (
        ...
        <form className="form-horizontal">
            ...
            <input type="text" className="form-control" ref={input => this.title = input} name="title" />
            ...
        </form>
        ...
        <button type="button" onClick={this.onSubmit} className="btn">Save</button>
        ...
    );
}

};