2014-10-28 6 views
55

TLDR Senden: Verwenden Sie defaultChecked statt geprüft, Arbeits jsbin hier http://jsbin.com/mecimayawe/1/edit?js,outputReagieren Checkbox nicht onChange

Der Versuch, die Einrichtung ein einfaches Kontrollkästchen, das das Etikett Text überqueren, wenn es aktiviert ist. Aus irgendeinem Grund wird handleChange nicht ausgelöst, wenn ich die Komponente verwende. Kann mir jemand erklären, was ich falsch mache?

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

Verbrauch:

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

Lösung:

geprüft verwenden, nicht die zugrunde liegende Wertänderung (scheinbar) lassen und somit nicht den onChange Handler nicht nennen. Umschalten auf defaultChecked scheint dies zu beheben:

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

Zuerst, warum nicht ein onChange hinzufügen, das tut einfach 'this.setState ({checked:! This.state.checked})' Einfacher als einen Wert speichern zu müssen. Dann ein ternärer Operator in der aktivierten attrubute: 'checked = {this.state.checked? 'checked': null} ' – zackify

+0

So begann es, aber es schien nie zu aktualisieren. Also fing ich an, hier und da aufzutun, um zu debuggen, was nicht gefeuert wurde. Im Idealfall gehen Sie zurück zum einfachsten Formular, wenn Sie fertig sind :) – jdarling

+0

Angenommen, Ihr mountNode ist ein tatsächlicher Dom-Knoten, müssten Sie 'this.refs.complete.getDOMNode(). Checked' verwenden. siehe fiddle http://jsfiddle.net/d10xyqu1/ – trekforever

Antwort

93

Um den Überprüfungsstatus Ihrer Checkbox zu erhalten der Weg wäre:

this.refs.complete.state.checked 

Die Alternative ist es von der Veranstaltung in die handleChange Methode übergeben zu bekommen:

event.target.checked 
+3

handleChange wird nie aufgerufen, egal, wenn du auf das Kontrollkästchen oder die Beschriftung klickst, wird handleChange nicht aufgerufen :(. – jdarling

+6

Probiere defaultChecked = {this. state.complete} anstelle von "checked" auf Ihrer Eingabe. – zbyte

+0

Das war es ... Gesucht für immer suchen und herum stochern. Wird die Frage mit vollständiger funktionierender Antwort aktualisieren, falls andere auch über diese hinweg rennen. – jdarling

1

In Material ui, Bundesstaat Ankreuzfeld kann als

01 abgerufen werden,
0

In dem Szenario, in dem Sie nicht möchten, den onChange-Handler für das Eingabe-DOM zu verwenden, können Sie die onClick-Eigenschaft als eine Alternative verwenden. Die defaultChecked, die Bedingung kann einen festen Zustand für V16 IINM verlassen.

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

Ich hoffe, dass dies jemand in der Zukunft hilft.