ReactJS를 사용하여 입력 필드의 값을 얻는 방법은 무엇입니까?


188

다음과 같은 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>
            ...
        );
    }

};

콘솔이 나에게주는 undefined-이 코드에 어떤 문제가 있습니까?


7
this.onSubmit.bind(this);
zerkms

니스-답변으로 추가하고 싶을 것입니다. (?)
JoeTidee

2
무엇에 대한 e.target.value바인드없이?
omarjmh

1
e.target.value가 입력 필드가 아닌 버튼을 타겟팅하지 않습니까?
JoeTidee

onSubmit클릭 할 때 (예 :) 제출 단추 (DOM 요소)에 메소드 를 바인딩해야합니다 onClick={this.onSubmit.bind(this)}. 그리고 양식의 제목 입력 값에 액세스하려면을 사용할 수 있습니다 onSubmit(event) { const title = event.target.elements.title.value; }.
tfmontague

답변:


10

MyComponent extends React.Component 클래스에서 생성자를 사용해야합니다.

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

그럼 당신은 제목의 결과를 얻을 것이다


315

작업하고있는 React 버전과 후크 사용 여부에 따라 여기에 세 가지 답변이 있습니다.

먼저 첫 번째 것들:

이됩니다 : 당신이 제대로 (protip이 일을 할 수 있도록이 작품을 어떻게 반응하는지 이해하는 것이 중요 슈퍼 . 방법을 수행하는 사실이 설명하는 방법으로 웹 사이트 반응에 튜토리얼 운동 반응을 통해 잘 작성의 가치가 실행하고, 커버 모든 기본 소지품). 여기서 "적절하게"는 브라우저에서 렌더링되는 응용 프로그램 인터페이스를 작성하고 있음을 의미합니다. 모든 인터페이스 작업은 "웹 페이지를 작성하는 데 익숙하지 않은"React에서 발생합니다 (React 앱이 "웹 페이지"가 ​​아니라 "앱"인 이유).

React 애플리케이션은 다음 두 가지를 기반으로 렌더링됩니다.

  1. 부모가 선언 한 구성 요소의 속성은 부모가 수명주기 내내 수정할 수있는 해당 구성 요소의 인스턴스를 만듭니다.
  2. 구성 요소 자체의 내부 상태로, 자체 수명주기 내내 자체적으로 수정할 수 있습니다.

당신은 명시 적으로 무엇을하고 하지 당신이 사용에 반응 말할 때 당신이 그 사용 후 HTML 요소를 생성하고 반작용 사용할 때하고 <input>, 예를 들어, 당신이 하지 의 HTML 입력 요소를 생성, 당신이 말하는되는 입력 오브젝트 반응 생성 반응 HTML 입력 요소 로 렌더링 되며 이벤트 처리는 HTML 요소의 입력 이벤트를 보지만 제어하지는 않습니다 .

React를 사용할 때 사용자 상호 작용으로 구성 요소의 상태를 변경하여 사용자에게 (종종 조작 가능한) 데이터를 제공하는 응용 프로그램 UI 요소를 생성 하면 응용 프로그램 인터페이스의 일부가 다시 렌더링되어 새 상태가 반영 될 수 있습니다. 이 모델에서 상태는 웹에서 브라우저의 DOM 인 "렌더링에 사용되는 UI 라이브러리"가 아니라 항상 최종 권한입니다. DOM은이 프로그래밍 모델에서 거의 후유증입니다. React가 사용하는 특정 UI 프레임 워크 일뿐입니다.

따라서 입력 요소의 경우 논리는 다음과 같습니다.

  1. 입력 요소를 입력하면
  2. 입력 요소에는 아무런 변화가 없지만 React가 이벤트를 가로 채서 즉시 종료했습니다 .
  3. React는 이벤트 처리를 위해 설정 한 기능으로 이벤트를 전달합니다.
  4. 이 기능 상태 업데이트를 예약 할 수 있습니다 .
  5. 이 경우 React는 해당 상태 업데이트 (비동기 적으로!)를 실행 render하고 업데이트 후 상태 업데이트 가 상태를 변경경우에만 호출을 트리거합니다 .
  6. 이 렌더링이 발생한 후에 만 UI에 "문자를 입력했다"고 표시됩니다.

이 모든 것은 밀리 초 단위 로 이루어 지지만, "페이지에서 입력 요소 만 사용"과 같은 방식으로 입력 요소에 입력 한 것처럼 보이지만 절대 그렇지 않습니다. 일어난.

따라서 React의 요소에서 값을 얻는 방법에 대해서는 다음과 같이 말했습니다.

ES5로 15 이하 반응

작업을 올바르게 수행하기 위해 구성 요소는 입력 필드를 통해 표시되는 상태 값을 가지며 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
    });
  }
});

따라서 React에 updateInputValue함수를 사용하여 사용자 상호 작용을 처리하고 setState, 상태 업데이트를 예약하는 데 사용 하며, render탭핑 한다는 사실은 상태를 업데이트 this.state.inputValue한 후 다시 렌더링하면 사용자가 입력 한 내용에 따라 업데이트 텍스트를 보게된다는 것을 의미합니다.

의견에 따른 부록

UI 입력은 상태 값을 나타냅니다 (사용자가 중간에 탭을 닫고 탭이 복원되면 어떻게되는지 고려하십시오. 입력 한 모든 값을 복원해야합니까? 그렇다면 그 상태입니다). 따라서 대형 양식에는 수십 또는 백 개의 입력 양식이 필요한 것처럼 느껴질 수 있지만 React는 UI를 유지 관리 가능한 방식으로 모델링하는 것입니다 .100 개의 독립적 인 입력 필드가없고 관련 입력 그룹이 있으므로 각각을 캡처합니다. 구성 요소에서 그룹화 한 다음 그룹 모음으로 "마스터"양식을 작성하십시오.

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

또한 거대한 단일 폼 구성 요소보다 유지 관리가 훨씬 쉽습니다. 상태 유지 보수를 통해 그룹을 구성 요소로 분할하십시오. 여기서 각 구성 요소는 한 번에 몇 개의 입력 필드 만 추적해야합니다.

또한 모든 코드를 작성하는 것이 "번거 롭다"고 생각할 수도 있지만, 이는 잘못된 저장입니다. 미래를 포함하여 귀하가 아닌 개발자는 실제로 모든 입력을 명시 적으로 연결하면 크게 이익을 얻을 수 있습니다. 코드 경로를 훨씬 쉽게 추적 할 수 있습니다. 그러나 항상 최적화 할 수 있습니다. 예를 들어 상태 링커를 작성할 수 있습니다

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']}/>
    });
  }
});

물론 이것의 개선 된 버전이 있으므로 https://npmjs.com 을 방문하여 가장 좋아하는 React 상태 연결 솔루션을 검색 하십시오 . 오픈 소스는 주로 다른 사람들이 이미 한 일을 찾고 모든 것을 처음부터 쓰는 대신 사용하는 것입니다.

반응 16 (및 15.5 과도) 및 '현대'JS

React 16부터 (15.5로 소프트 스타트) createClass콜은 더 이상 지원되지 않으며 클래스 구문을 사용해야합니다. 명백한 클래스 구문을뿐만 아니라이 두 가지를 변경 this문맥은 그 바인딩 createClass때문에 여전히 작업 메이크업 확실히 당신이 "지방 화살표"표기법을 사용하는 것을 보장하기 위해 "무료"할 수있는 this익명의 기능을 유지 상황 onWhatever등, 핸들러 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
    });
  }
});

또한 사람들 bind이 생성자에서 다음과 같이 모든 이벤트 처리 함수에 사용하는 것을 보았을 것입니다 .

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

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

하지마

거의 모든 시간을 사용할 때 bind"잘못하고 있습니다"라는 속담이 적용됩니다. 클래스는 이미 객체 프로토 타입을 정의하므로 이미 인스턴스 컨텍스트를 정의합니다. bind그 위에 두지 마십시오 . 생성자의 모든 함수 호출을 복제하는 대신 일반 이벤트 전달을 사용하십시오. 중복으로 인해 버그가 증가하고 코드를 호출하는 대신 생성자에 문제가있을 수 있으므로 오류를 추적하기가 훨씬 더 어렵습니다. 뿐만 아니라 귀하와 함께 일하는 다른 사람에게 유지 관리 부담을 주어야합니다.

예, 반응 문서가 괜찮다고 말합니다. 그렇지 않습니다.

후크가있는 기능 컴포넌트를 사용하여 반응식 16.8

React 16.8부터 함수 구성 요소 (즉 props, 클래스를 쓰지 않고 구성 요소 클래스의 인스턴스 인 것처럼 문자 그대로 인수로 사용 하는 함수 )도 hooks 사용하여 상태를 제공 할 수 있습니다 .

전체 클래스 코드가 필요하지 않고 단일 인스턴스 함수가 ​​필요한 경우 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>
  );
}

이전에는 클래스와 함수 구성 요소의 비공식적 인 구별이 "함수 구성 요소에 상태가 없음"이라는 것이 었으므로 더 이상 그 뒤에 숨길 수 없습니다. 함수 구성 요소와 클래스 구성 요소의 차이는 여러 페이지에 걸쳐 잘 나와 있습니다. 당신이하고있는 일을 알기 때문에 자신이 프로그래밍 할 수있는 최선의 솔루션을 선택했는지 여부를 알 수 있도록 읽은 반응 문서 ( 단순히 하나의 라이너 설명이 없으므로 잘못 해석 할 수 있습니다!) 당신이 겪고있는 문제에서.


4
너무 많은 상태를 사용하는 것이 좋지 않다고 말하는 온라인 기사를 읽었습니다. 내 신청서의 특정 형태에는 약 100 개의 양식 필드가 있습니다. 상태를 저장하는 함수를 정의하는 것은 불필요하게 어려운 일을하는 것처럼 느껴집니다. onClick = {this.onSubmit.bind (this)}를 사용할 수 있다면 값을 얻는 좋은 방법 인 것 같습니다 (원하는 경우 구성 요소 상태를 설정하십시오)-이에 대한 의견을 부탁드립니다.
JoeTidee

5
똑똑한 코드를 작성하십시오. 양식 입력은 가장 확실하게 상태입니다 (사용자가 중간에 탭을 닫고 탭이 복원되면 어떻게되는지 고려하십시오. 채워진 모든 값을 복원해야합니까? 예? 해당 상태 ) 약간의 상태 유지 관리 코드를 작성하십시오. 페이스 북은 수백 가지의 폼 값을 가지고 있으며 광기에 대한 해결책은 React였습니다. 정말 잘 작동 합니다. 상태를 계속 사용하면서 코드를 조금 더 쉽게 만드는 한 가지 방법은 다시 양방향 사이트 연결 을 사용 하는 것 입니다. 읽을만한 가치가 있습니다! =)
Mike 'Pomax'Kamermans

2
또한 "100 개의 필드"는 대부분 관련이 없습니다. 폼은 100 개의 요소가 아니기 때문에 여러 개의 입력이있는 여러 섹션이므로 양식을위한 그룹화 컴포넌트를 사용하여 각 섹션을 고유 한 컴포넌트로 만듭니다. 여러 떼. 이것은 일반적으로 10 개 미만의 입력을 담당하는 구성 요소를 만들어 내고 갑자기 정보 아키텍처가 훨씬 더 의미가 있습니다. 브라우저 작업으로 양식 제출은 물론 "귀하의 양식"을보고 모든 것을 한 번에 제출합니다. 깨끗하고 대상이 지정된 UI 디자인.
Mike 'Pomax'Kamermans

2
의견 주셔서 감사합니다. 그러나 React v15에서 상태 연결이 더 이상 사용되지 않는다는 것을 알았습니다.
JoeTidee

3
@JasonChing 그런 다음 코드에 잠재적 인 버그를 작성했습니다. 웹 페이지에 솔루션 "모든 모든을 종료 할"되지 않은 반응, 그것은 인터페이스를 구축하기위한 프레임 워크, 그리고 그것은 당신의 사용자가 상호 작용, DOM을하지 상호 작용 할 (뒤늦게 상태 관리 및 실제 UI 렌더링에 대한 책임 반응 : DOM 업데이트는 UI의 상태를 시각적으로 반영하기 위해 단순히 비동기적인 (그러나 엄청나게 빠른) 마지막 단계입니다. 이것을 우회하고 싶다면 더 중요한 질문은 왜 React를 사용하는 것입니까? 당신이 그것을 잘못 사용하고있는 가장 좋은 신호는 React와 jQuery를 결합하는 것입니다.
Mike 'Pomax'Kamermans

17

다음과 같은 방법으로 입력 필드 값을 가져옵니다.

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

1
왜 "setState"를 사용합니까? 다시 렌더링해야합니다. 그렇지 않습니까?
Luca Davanzo

15

반응 16에서, 나는

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

로드시 필드가 자동으로 채워지면 작동하지 않습니다
SeanMC

4

"this"를 updateInputValue (evt) 함수에 바인딩 하여이 작업을 수행했습니다.

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

그러나 input value = {this.state.inputValue} ... 좋은 생각이 아닙니다.

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

2

오류는 클래스를 사용하기 때문에 발생하며 클래스를 사용할 때 제대로 작동하려면 this를 사용하여 함수를 바인딩해야합니다. 어쨌든 우리가 왜 "this"를해야하고 "this"가 자바 스크립트에서 무엇을해야하는지 많은 튜토리얼이 있습니다.

제출 버튼을 수정하면 작동해야합니다.

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

또한 콘솔에서 해당 입력 값을 표시하려면 var title = this.title.value;


2
"this"에 대해 더 알고 싶다면이 링크가 도움이 될 것입니다.
Soroush Bk


2

<input>고유 한 ID를 부여하십시오

<input id='title' ...>

그런 다음 표준 웹 API 를 사용 하여 DOM에서이를 참조하십시오.

const title = document.getElementById('title').value

키를 누를 때마다 React 상태를 지속적으로 업데이트 할 필요가 없습니다. 필요할 때 간단히 가치를 얻으십시오.


1
// 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="johdoe@somewhere.com" />

대답은 질문에 도움이 될 수 있지만 항상 설명을 추가하는 것이 좋습니다. 추가하려면 2 분이 걸립니다. 이렇게하면 향후 사용자에 대한 답변도 향상됩니다.
DaFois

물론 그렇게 할 것입니다.
Kidali Kevin

0

'onChange'기능을 추가하지 않고도 입력 값을 얻을 수 있습니다.

입력 요소에 'ref attr'을 추가하십시오.

그런 다음 this.refs를 사용하여 필요할 때 입력 값을 가져옵니다.


3
더 이상 권장하지 않습니다.
JoeTidee

1
그것들을 사용할 수 있지만 props 및 콜백을 사용하여 데이터 흐름을 한 방향으로 유지하는 것이 좋습니다.
JoeTidee

참조를 올바르게 추가하는 예제, 즉 레거시 문자열 대신 참조 콜백 사용을 추가하는 것이 좋습니다.
JoeTidee

0

귀하의 심판을 다음으로 변경하십시오 : ref='title'삭제 name='title' 후 삭제 var title = this.title하고 쓰십시오 :

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

또한 추가해야합니다 .bind(this)this.onSubmit

(이것은 상당히 비슷한 내 경우에는 효과가 있었지만 대신 onClick내가 가지고 있었고 onSubmit={...}( <form onSubmit={...} ></form>))


0

클래스 컴포넌트를 사용하는 경우 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

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

};

0

제어되지 않은 필드 사용 :

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        console.log(e.target.neededField.value);
    }

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

};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.