React Checkbox onChange göndermiyor


136

TLDR: Kontrol edilmiş, çalışan jsbin yerine defaultChecked kullanın .

İşaretlendiğinde etiket metninin üzerini çizecek basit bir onay kutusu oluşturmaya çalışıyorum. Bazı nedenlerden dolayı, bileşeni kullandığımda handleChange ateşlenmiyor. Neyi yanlış yaptığımı kimse açıklayabilir mi?

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    console.log('handleChange', this.refs.complete.checked); // Never gets logged
    this.setState({
      complete: this.refs.complete.checked
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            checked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});

Kullanımı:

React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);

Çözüm:

İşaretli kullanmak temel değerin değişmesine izin vermez (görünüşte) ve bu nedenle onChange işleyicisini çağırmaz. Varsayılana geçmek Checked bunu düzeltir gibi görünüyor:

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    this.setState({
      complete: !this.state.complete
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            defaultChecked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});

3
Öncelikle, this.setState({checked: !this.state.checked})bir değeri saklamaktan daha kolay olan bir onChange eklemeye ne dersiniz ? Ardından, kontrol edilen özde bir üçlü operatör:checked={this.state.checked ? 'checked': null}
2014

İşte böyle başladı, ama hiçbir zaman güncellenmedi. Bu yüzden, neyin kovulmadığında hata ayıklamak için orada burada kabartmaya başladım. İdeal olarak, tamamlandığında en basit forma geri dönecektir :)
jdarling

MountNode'unuzun gerçek bir dom düğümü olduğunu varsayarsak, kullanmanız gerekir this.refs.complete.getDOMNode().checked. bkz. fiddle jsfiddle.net/d10xyqu1
trekforever

Dom düğümünü almak yerine sadece durumu kullanabilir: jsfiddle.net/d10xyqu1/1 İyi çalışıyor, bir şeyi yanlış yazmış olmalısınız.
2014

2
TLDR yorumunu yoksayın - defaultChecked her zaman cevap değildir
Chris

Yanıtlar:


207

Onay kutunuzun işaretli durumunu almak için yol şöyle olacaktır:

this.refs.complete.state.checked

Alternatif, handleChangemetoda geçirilen olaydan elde etmektir :

event.target.checked

3
handleChange hiçbir zaman çağrılmaz, onay kutusunu veya etiketi tıklamanız önemli değil, handleChange çağrılmıyor :(.
jdarling

13
Girişinizde "işaretli" yerine defaultChecked = {this.state.complete} kullanmayı deneyin.
zbyte

İşte buydu ... Sonsuza kadar bakıp etrafta dolaşarak arandı. Başkalarının da bununla karşılaşması durumunda soruyu eksiksiz çalışan yanıtla güncelleyecektir.
jdarling

Ama neden - aynı sorunu yaşıyorsunuz ama checkedkontrollü bileşenler için kullanmanız gerekiyor : /
Dominic

4
ayar checked, durumun bileşenin dışında yönetildiği anlamına gelir. Kullanıcı tıkladığında handleChangehiçbir durum güncellenmediği için arayacak bir şey yoktur. Bunun yerine, onClickorada bir durum güncellemesini dinlemeniz ve tetiklemeniz gerekir .
zbyte

29

Bu tür durumlarda ref kullanmamak daha iyidir. kullanın:

<input
    type="checkbox"
    checked={this.state.active}
    onClick={this.handleClick}
/>

Bazı seçenekler var:

checked vs defaultChecked

Eski devlet değişiklikleri hem yanıt vereceğini ve tıklama. İkincisi, durum değişikliklerini görmezden gelir.

onClick vs onChange

İlki her zaman tıklamaları tetikler. Öğede checkedözellik varsa, ikincisi tıklamaları tetiklemez input.


10

Senaryoda, DOM girişinde onChange işleyicisini kullanmak İSTEMEZSİNİZ, onClicközelliği alternatif olarak kullanabilirsiniz . defaultCheckedDurum v16 IINM için sabit bir durum bırakabilir.

 class CrossOutCheckbox extends Component {
      constructor(init){
          super(init);
          this.handleChange = this.handleChange.bind(this);
      }
      handleChange({target}){
          if (target.checked){
             target.removeAttribute('checked');
             target.parentNode.style.textDecoration = "";
          } else {
             target.setAttribute('checked', true);
             target.parentNode.style.textDecoration = "line-through";
          }
      }
      render(){
         return (
            <span>
              <label style={{textDecoration: this.props.complete?"line-through":""}}>
                 <input type="checkbox"
                        onClick={this.handleChange}
                        defaultChecked={this.props.complete}
                  />
              </label>
                {this.props.text}
            </span>
        )
    }
 }

Umarım bu gelecekte birine yardımcı olur.


10

handleChangeŞuna benzeyen bir işleviniz varsa :

handleChange = (e) => {
  this.setState({
    [e.target.name]: e.target.value,
  });
}

onChangeBir metin girişi gibi davranması için özel bir işlev oluşturabilirsiniz :

<input
  type="checkbox"
  name="check"
  checked={this.state.check}
  onChange={(e) => {
    this.handleChange({
      target: {
        name: e.target.name,
        value: e.target.checked,
      },
    });
  }}
/>

değil handleChangeüzerinde inputolmalıdır this.handleChange?
Ardhi

5

Birinin evrensel bir olay işleyicisi araması durumunda, aşağıdaki kod az ya da çok kullanılabilir ( ad özelliğinin her girdi için ayarlandığı varsayılarak ):

    this.handleInputChange = (e) => {
        item[e.target.name] = e.target.type === "checkbox" ? e.target.checked : e.target.value;
    }

2

onChange, defaultChecked kullanılırken mobilde handleChange öğesini çağırmaz. Alternatif olarak onClick ve onTouchEnd'i kullanabilirsiniz.

<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete} />;

1

Malzeme kullanıcı arayüzünde, onay kutusu durumu şu şekilde getirilebilir:

this.refs.complete.state.switched
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.