ReactJS에서 양식 데이터 가져 오기


199

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필드 에 무엇을 써야 합니까?


11
@ssorallen 무슨 말이 안됩니까? asker는 SPA를 구축 할 수 있으며 일반적인 HTML 양식처럼 양식을 제출 하지 않을 수 있습니다 . 이들이 원하면 조치를 정의하고 이벤트 핸들러를 제거합니다.
developerbmw

6
참고 : onSubmit버튼 클릭 대신 양식을 처리해야합니다. 이렇게하면 Enter 키를 눌러 양식을 제출하는 사용자도 처리 할 수 ​​있습니다.
developerbmw

10
<form>A를 <button><input>와는 type=submit사용자 프레스 폼의의에 입력 할 때 제출 얻을 것이다 <input type=text>. onClick단추 중 하나 에 의존하는 경우 사용자는 단추를 클릭하거나 초점을 맞추고 Enter / 스페이스 바를 눌러야합니다. 를 사용 onSubmit하면 두 가지 사용 사례가 모두 활성화됩니다. 양식이 제출을 위해 Enter를 지원하지 않으면 양식이 손상 될 수 있습니다.
Ross Allen

답변:


167

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의 양방향 데이터 바인딩 도우미 믹스 인을 사용하여 동일한 결과를 얻을 수 있었지만 이제는 위와 같이 값 및 변경 처리기를 설정하는 것이 더 이상 사용되지 않습니다.

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

설명서는 여기에 있습니다 : 양방향 바인딩 도우미 .


3
의 기능을 올바르게 모방하려면 valueLink첫 번째 예 value에서 입력 요소를 설정해야 합니다. 그렇지 않으면 값은 React 용어 로 "제어되지 않습니다" . <input ... value={this.state.password}>.
Ross Allen

10
버튼으로 onClick 대신 양식과 함께 onSubmit을 사용할 수도 있습니다
sai

58
양식의 각 요소에 상태를 사용하는 이유는 무엇입니까? 다른 사람은 이것이 나쁜 패턴이라고 생각합니까?
eveevans

6
valueLink가 사용되지 않는 것 같습니다
Matt Broekhuis

3
클라이언트 쪽에서 암호를 평생 텍스트로 저장하지 않습니까? 암호 필드에는 적합하지 않은 것 같습니다.
NewbiZ

166

이를 수행하는 몇 가지 방법이 있습니다.

1) 인덱스로 폼 요소 배열에서 값 가져 오기

handleSubmit = (event) => {
  event.preventDefault();
  console.log(event.target[0].value)
}

2) HTML에서 이름 속성 사용

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

1
이것은 환상적인 답변입니다. 이를 수행하는 여러 가지 방법을 나열 해 주셔서 감사합니다.
Beau Smith

옵션 2 가 작동하지 않습니다. 입력의 이름이 "username"인 경우에도 "elements"또는 "username"속성이 없습니다.
Madacol

@Madacol 이런 일이 생길 수 있습니다
Aliaksandr Sushkevich

45

다른 방법은 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에서 라디오 버튼을 어떻게 사용합니까?에 설명 된 많은 이유가 있습니까? 이 방법이 항상 최선은 아니지만 간단한 경우에 유용한 대안을 제시합니다.


1
이 솔루션이 실제로 더 좋고 질문에 사용할 수 없었습니까? 아니면 "추악한"방법입니까?
Wagner Leonardi

4
실제로 당신은 React.findDOMNode this.refs.theInput에게 이미 HTML 노드 필요가 없습니다
파리 드 자카 Alnamrouti

23

심판을 다루는 쉬운 방법 :

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;


2
이 방법은 언젠가 더 이상 사용되지 않을 것입니다. 참조는 문자열이 아닌 콜백에만 사용해야합니다. 자세한 내용은 : facebook.github.io/react/docs/refs-and-the-dom.html
데이비드 LABBE

멋있는! :) 나는 이것을 위해 Object.keys()다음과 map()같이 사용 하고 싶다 :Object.keys(this.refs).map(field => formData[field] = this.refs[field].value)
Francis Rodrigues

예, 문자열 참조는 더 이상 사용되지 않습니다. 지금하는 더 좋은 방법은 onChange 콜백을 사용하는 것입니다. 여전히 심판을 사용하려면이 synctax를 사용할 수 있습니다 :<input type="text" ref={(input) => { this.textInput = input; }} />
E. Fortes

나는 @ E.Fortes, onChange 콜백 메소드를 설명해 주시겠습니까? 당신이 할 수 있다면 대단히 감사합니다. 답장을 알려주 시려면 저를 태그하십시오.
Simona Adriani

간단한 방법은 다음과 같습니다 (코드 포맷터가 작동하지 않습니다) : class NameForm extends React.Component {constructor (props) {super (props); this.state = {값 : ''}; this.handleChange = this.handleChange.bind (this); } handleChange (event) {this.setState ({value : event.target.value}); } render () {return (<form> <label> 이름 : <input type = "text"value = {this.state.value} onChange = {this.handleChange} /> </ label> </ form>); }}
E. Fortes

22

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

이 중간 기사 : 방금 반응하는 양식 처리 방법을 참조하십시오.

이 메소드는 제출 단추를 누른 경우에만 양식 데이터를 가져옵니다. 훨씬 더 깨끗한 IMO!


완벽한 답변. 👌
Michal

16

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
}

이 플러스 'console.log (user);'실행 사용 가능한 값이없는 객체를 제공합니다! 어떤 의견?
M at

@MahdiRafatjah ¯ \ _ (ツ) _ / ¯-
Michael Schock

내 친구가 문서를 반응 시키라고 나에게 말했고
M at

1
좋은, 그것은 훨씬 더 깨끗해 보인다 =)
Michael Schock

13

다음과 같은 접근법을 제안합니다.

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

}

컴포넌트를 다시 렌더링하지 않는 경우 현재 상태에 따라 각 요소의 값을 설정하는 방법은 무엇입니까? 예 : "value = {this.state. destination}". 또한 다시 렌더링하지 않으면 양식에서 반응 유효성 검사를 실행할 수 없습니다
Avishay28

13

모든 입력 / 텍스트 영역에 이름이 있으면 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가없는 완전히 제어되지 않은 양식 😊


12

ref를 사용하지 않고 OnChange이벤트로 상태를 재설정하지 않으려 는 경우 간단한 OnSubmit 핸들을 사용하고 FormData객체를 반복하면 됩니다. 이 예제는 React Hooks를 사용하고 있습니다 :

const LoginPage = () =>{
    const handleSubmit = (event) => {
        const formData = new FormData(event.target);
        event.preventDefault();
        for (var [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>)
        }

좋은 대답이지만, nitpick은 var 이외의 완벽한 솔루션을 제거 할 수 있습니까!
Louis345

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

4
이 답변이 올바른 방법 인 이유를 설명해주십시오.
Tim Hutchison

1
텍스트 형식을 변경하는 한 가지 방법 만 사용합니다
Yurii Kosygin

암호는 보안 문제의 일부인 반응 도구에서 볼 수 있습니까?
Neil

5

입력을 다음과 같이 지정하십시오.

<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />

그런 다음 핸들에서 액세스 할 수 있습니다.

handleLogin: function(e) {
   e.preventDefault();
    console.log(this.refs.email.value)
    console.log(this.refs.password.value)
}

5

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


4

자바 스크립트의 많은 이벤트에서 우리는 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>
    );
  }
}

4

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

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>

여기에 첨부 된 출력 이미지


설명도 제공해주세요.
BlackBeard

2
나는 이것을 설명하려고 노력할 것이다. handleSubmit () 함수에서 키는 양식 ( 'formData [data]'문)에있는 모든 입력의 'ref'속성이고 값은 입력 값인 오브젝트 (formData)를 빌드합니다. 이 'ref'속성 ( 'this.refs [data] .value'문)을 사용하십시오. 'formData [data] = this.refs [data] .value'를 사용하면이 오브젝트를 빌드하게됩니다. 말 그대로 : formData [ 'username'] = (사용자 이름 입력 값) 및 formData [ 'password'] = (암호 입력 값) 출력은 다음과 같습니다. {user : 'blablabla', password : 'xxx '}
Simona Adriani

설명해 주셔서 감사합니다 @SimonaAdriani.
밀라노 Panigrahi

2

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

1
this.submitForm.bind (this)는 다음과 같아야합니다.
this.submitForm

오류 : 상태 비 저장 함수 구성 요소는 참조를 가질 수 없습니다.
holms

Meteor (v1.3)를 사용하고 있습니까?
Joe L.

1

사용자 경험을 향상시키기 위해; 사용자가 제출 단추를 클릭하면 양식에 먼저 보내는 메시지를 표시하도록 할 수 있습니다. 서버로부터 응답을 받으면 그에 따라 메시지를 업데이트 할 수 있습니다. 우리는 체인 상태에 의해 React에서 이것을 달성합니다. 아래의 코드 또는 스 니펫을 참조하십시오 .

다음 방법은 첫 번째 상태를 변경합니다.

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

코드 펜


1

요소 이름이 여러 번 나타나는 경우 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);
};

이 경우 델은 배열이 아니라 RadioNodeList이며 Iterable이 아닙니다. forEach ()는리스트 클래스의 내장 메소드입니다. 여기서 map () 또는 reduce ()를 사용할 수 없습니다.


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