ReactJS'de form verilerini alma


201

Benim gibi basit bir form var, şöyle 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() { ... }Erişim Emailve Passwordalanlara ne yazmalıyım ?


6
Not: onSubmitdüğmeyi tıklatmak yerine formu ele almalısınız - bu şekilde enter'a basarak formu gönderen kullanıcıyı da ele alırsınız.
developerbmw

11
A veya ile <form>birlikte A , kullanıcı formun herhangi birinde Enter tuşuna bastığında gönderilir . Bir düğmeden birine güveniyorsanız , kullanıcının düğmeyi tıklaması veya odaklaması ve Enter / Ara Çubuğu'na basması gerekir. Kullanımı her iki kullanım durumunu da etkinleştirir. Formlar Enter'a göndermeyi desteklemediğinde bozuk hissedebilirler. <button><input>type=submit<input type=text>onClickonSubmit
Ross Allen

Yanıtlar:


167

changeBileşenin durumunu güncellemek ve içeriğe erişmek için girişlerdeki olayları kullanın 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);
}

Çalışma keman .

Ayrıca, dokümanları okuyun, form işlemeye adanmış bir bölüm var: Formlar

Daha önce, aynı şeyi elde etmek için React'in iki yönlü veri bağlama yardımcı karışımını da kullanabilirsiniz, ancak şimdi değeri ayarlamak ve işleyiciyi değiştirmek lehine kaldırılmıştır (yukarıdaki gibi):

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

Belgeler burada: İki Yönlü Bağlayıcı Yardımcıları .


3
İşlevini doğru şekilde taklit etmek valueLinkiçin ilk örneğiniz valuegiriş öğelerini ayarlamalıdır . Bu olmadan, React teriminde değerler "kontrolsüz" olur. <input ... value={this.state.password}>.
Ross Allen

10
Ayrıca düğme ile yerine onClick şeklinde bir onsubmit kullanabilirsiniz
sai

60
Neden formun her öğesi için bir durum kullanılıyor? Başka biri bunun kötü bir model olduğunu düşünüyor mu?
eveevans

6
Görünüşe göre valueLink kullanımdan kaldırıldı
Matt Broekhuis

3
Bu, parolayı tüm zaman boyunca istemci tarafında açık metin olarak saklamıyor mu? Bu bir şifre alanı için gerçekten uygun görünmüyor.
NewbiZ

168

Bunu yapmanın birkaç yolu var:

1) Dizine göre form öğeleri dizisinden değerler alma

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

2) HTML'de ad özniteliğini kullanma

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) refs kullanma

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

<input type="text" name="username" ref={node => (this.inputNode = node)}/>

Tam örnek

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
Bu harika bir cevap. Bunu yapmanın birden fazla yolunu listelediğiniz için teşekkür ederiz.
Beau Smith

Seçenek 2 benim için çalışmıyor.
Girişimin

@Madacol bu olabilir aynı adı taşıyan birkaç giriş var
Aliaksandr Sushkevich

46

Alternatif bir yaklaşım, refözniteliği kullanmak ve değerlere başvurmaktır this.refs. İşte basit bir örnek:

render: function() {
    return (<form onSubmit={this.submitForm}>
        <input ref="theInput" />
    </form>);
},
submitForm: function(e) {
    e.preventDefault();
    alert(React.findDOMNode(this.refs.theInput).value);
}

React belgelerinde daha fazla bilgi bulunabilir: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute

React'ta radyo düğmelerini nasıl kullanırım? Bölümünde açıklanan birçok nedenden dolayı. bu yaklaşım her zaman en iyisi değildir, ancak bazı basit durumlarda yararlı bir alternatif sunar.


1
Bu çözüm gerçekten daha mı iyi ve soru zamanında mevcut değil mi, yoksa "çirkin" bir yol mu?
Wagner Leonardi

4
aslında React.findDOMNode'a ihtiyacınız yok this.refs.theInput zaten bir html düğümü
Fareed Alnamrouti

24

Michael Schock'un cevabına ekleme:

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

Bu Orta makaleye bakın: Formları Just React ile İşleme

Bu yöntem, form verilerini yalnızca Gönder düğmesine basıldığında alır. Çok daha temiz IMO!


Mükemmel cevap. 👌
Michal

23

Refs ile başa çıkmanın kolay bir yolu:

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
Bu yöntem gelecekte bir gün kullanımdan kaldırılacaktır. Referanslar yalnızca geri aramalarla kullanılır, dizelerle değil. Daha fazla bilgi için: facebook.github.io/react/docs/refs-and-the-dom.html
David Labbe

Güzel! :) Bunu kullanmak için Object.keys()takip etmeyi map()seviyorum:Object.keys(this.refs).map(field => formData[field] = this.refs[field].value)
Francis Rodrigues

Evet, dize başvuruları kullanımdan kaldırıldı. Bunu şimdi yapmanın daha iyi bir yolu onChange geri aramasını kullanmaktır. Eğer hala refs kullanmak istiyorsanız bu sözdizimini kullanabilirsiniz:<input type="text" ref={(input) => { this.textInput = input; }} />
E. Fortes

I @ E.Fortes, onChange geri arama yöntemini açıklayabilir misiniz? İstersen çok teşekkür ederim. Lütfen beni etiketleyin, böylece cevabınızdan haberdar olacağım.
Simona Adriani

basit bir yol olurdu (üzgünüm kod biçimlendirici çalışmıyor): sınıf NameForm React.Component {yapıcı (sahne) {süper (sahne) genişletir; this.state = {değer: ''}; this.handleChange = this.handleChange.bind (this); } handleChange (event) {this.setState ({value: event.target.value}); } render () {return (<form> <label> Adı: <giriş türü = "metin" değeri = {this.state.value} onChange = {this.handleChange} /> </label> </form>); }}
E. Fortes

16

onClickDüğmedeki olay işleyiciyi onSubmitformdaki bir işleyiciye geçirebilirsiniz :

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

Daha sonra FormDataformu ayrıştırmak için kullanabilirsiniz (ve isterseniz bir JSON nesnesi girdilerinden oluşturabilirsiniz).

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
}

Bu artı 'console.log (kullanıcı);' çalıştırılıyor kullanılabilir değeri olmayan bir nesne verir! Herhangi bir görüşünüz var mı?
, M

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

bir arkadaşım beni belgeye tepki vermem
M

1
güzel, çok daha temiz görünüyor =)
Michael Schock

13

Aşağıdaki yaklaşımı öneririm:

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

}

Bileşeni yeniden göndermiyorsanız, her bir öğenin değerini geçerli duruma göre nasıl ayarlayabilirsiniz? "value = {this.state. destination}". Ayrıca, yeniden
göndermiyorsanız

13

Tüm girişlerinizin / metin alanınızın bir adı varsa, tümünü event.target kaynağından filtreleyebilirsiniz:

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

OnChange yöntemleri, değeri, defaultValue olmadan tamamen kontrolsüz form 😊


13

Ref ile OnChangeolayı sıfırlamak ve olayı sıfırlamak istemeyenler için , basit OnSubmit tutamacını kullanabilir ve FormDatanesne boyunca döngü yapabilirsiniz . Bu örnek React Hooks kullanıyor:

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

Harika cevap, ama bir nitpick var aksi takdirde mükemmel bir çözüm kaldırabilir!
Louis345

5

Ayrıca, bu da kullanılabilir.

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
Lütfen bu cevabın neden doğru yol olduğunu açıklayan bir açıklama ekleyin.
Tim Hutchison

1
Metin formunu değiştirmek için yalnızca bir yöntem kullanıyorum
Yurii Kosygin

Parola, tepki geliştirme araçlarında, bir güvenlik sorununun bitinde mi görülebilir?
Neil

5

Girdilerinize bu şekilde referans verin

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

o zaman sapınıza erişebilirsiniz.

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

5

Es6 yıkıcı ile daha net örnek

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

Javascript'teki birçok olayda, eventhangi olayın gerçekleştiğini ve değerlerin neler olduğunu vb. İçeren bir nesneye sahibiz .

ReactJ'lerde de formlarla kullandığımız şey budur ...

Kodunuzda durumu yeni değere ayarlarsınız ... şöyle bir şey:

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;

Ayrıca bu, React v.16'daki form örneğidir, tıpkı gelecekte oluşturacağınız forma referans olarak:

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 durumunu kullanarak böyle kullanın:

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

Çıktı görüntüsü buraya iliştirilmiş


Lütfen bir açıklama da sağlayın.
Kara

2
Parlak bulduğum bunu açıklamaya çalışacağım. HandleSubmit () işlevinde, anahtarın formdaki her girdinin 'ref' özniteliği ('formData [data]' ifadesi) olduğu ve değerin girdinin değeri olduğu bir nesne (formData) oluşturuyorsunuz bu 'ref' özniteliğiyle ('this.refs [data] .value' ifadesi). 'FormData [data] = this.refs [data] .value' ile bu nesneyi oluşturuyorsunuz. Kelimenin tam anlamıyla şöyle diyorsunuz: formData ['username'] = (kullanıcı adı girişinin değeri) ve formData ['password'] = (şifre girişinin değeri) Çıktı: {user: 'blablabla', şifre: 'xxx '}
Simona Adriani

Açıklama için @SimonaAdriani teşekkür ederim.
Milan Panigrahi

2

Bu, Meteor (v1.3) kullanıcılarına yardımcı olabilir:

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) sadece şöyle olmalıdır: this.submitForm
rekarnar

Hata: Durum bilgisi olmayan işlev bileşenlerinde referans olamaz.
17'de holms

Meteor (v1.3) kullanıyor musunuz?
Joe L.

1

Kullanıcı deneyimini geliştirmek; kullanıcı gönder düğmesini tıkladığında, formun önce bir gönderme mesajı göstermesini sağlamayı deneyebilirsiniz. Sunucudan bir yanıt aldığımızda, mesajı uygun şekilde güncelleyebilir. Bunu React'ta durumları zincirleyerek başarıyoruz. Aşağıdaki kod kalemi veya snippet'lere bakın:

Aşağıdaki yöntem ilk durum değişikliğini yapar:

handleSubmit(e) {
    e.preventDefault();
    this.setState({ message: 'Sending...' }, this.sendFormData);
}

React yukarıdaki Gönderme mesajını ekranda gösterir göstermez, form verilerini sunucuya gönderecek yöntemi çağırır: this.sendFormData (). Basit olması için bunu taklit etmek üzere bir setTimeout ekledim.

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 uygulamasında this.setState () yöntemi yeni özelliklere sahip bir bileşen oluşturur. Böylece, form bileşeninin render () yönteminde sunucudan aldığımız yanıt türüne bağlı olarak farklı davranacak bazı mantık da ekleyebilirsiniz. Örneğin:

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

codepen


1

Bir öğe adının birden çok tekrarlanması durumunda forEach () kullanmanız gerekir.

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

Bu durumda dels bir dizi değil, bir RadioNodeList olduğunu ve Yinelenebilir olmadığını unutmayın. ForEach (), liste sınıfının yerleşik bir yöntemidir. Burada bir harita () veya azaltma () kullanamazsınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.