2017-10-28 1 views
1

Ich habe das Gefühl, dass ich das schon millionenfach gemacht habe, aber möglicherweise nicht mit einer Mapping-Funktion. Ich habe eine Sammlung von Aktivitäten, die ich bin Kontrollkästchen Erstellung mit dem Code lautet wie folgt (__map kommt von Lodash by the way):Reagieren, warum beschriften nicht onChange für Checkbox?

<div className="activity-blocks"> 
{ 
    __map(this.state.activities, (activity, i) => { 
     return (
      <div key={ i } className="single-activity"> 
       <input id={ `register-activity-${ i }` } 
        type="checkbox" className="register-multiselect" 
        name="main_activity" checked={ !!activity.checked } 
        onChange={ (e) => this.toggleActivity(e, activity.id) } 
       /> 
       <label htmlFor={ `register-activity-${ i }` }>{ activity.name }</label> 
      </div> 
     ) 
    }) 
} 

Mein onChange Handler sieht wie folgt aus:

toggleActivity(e, activityId) { 
    let activities = { ...this.state.activities }; 

    __forEach(this.state.activities, (activity) => { 
     if (activityId === activity.id) { 
      activity = __assign(activity, { checked: e.target.checked }); 
      return false; 
     } 
    }); 

    this.setState({ activities: activities }); 
} 

Der Handler funktioniert gut, es ist meist als Referenz. Mein Problem ist, dass das Label den Handler nicht auslöst. Ich habe nur die Checkbox-Eingabe ohne Label getestet und es feuert den Handler ab. Weiß jemand, warum das Label das nicht tut?

Weitere Informationen: Ich hatte dieses Problem vorher, aber es stellt sich heraus, dass es sich um einen ID-Mismatch oder etwas Einfaches handelt. Das glaube ich diesmal nicht.


bearbeiten Ich habe so ziemlich alle den Code aus meiner Datei gelöscht und Slawa Antwort unten und es immer noch nicht wie erwartet verhalten aufgenommen. Hier ist der Code, einschließlich aller Importe, die Klassenstruktur und alle unnötigen Code gezupft, einschließlich Arten:

import React from 'react'; 
import __forEach from 'lodash/forEach'; 
import __assign from 'lodash/assign'; 
import __map from 'lodash/map'; 

export default class RegisterActivities extends React.Component { 
    constructor(props) { 
     super(props); 

     this.state = { 
      activities: [ 
       { 
        id: 1, 
        name: 'label-1' 
       }, 
       { 
        id: 2, 
        name: 'label-2' 
       }, 
       { 
        id: 3, 
        name: 'label-3' 
       } 
      ], 
     } 
    } 

    toggleActivity(e, activityId) { 
     const { activities } = this.state; 

     const updated = activities.map((activity) => { 
      if (activity.id === activityId){ 
       return { 
        ...activity, 
        checked: e.target.checked 
       } 
      } 

      return activity; 
     }); 
    } 

    render() { 
     return (
      <div> 
       <p>what do you do?</p> 
       <div> 
       { 
        __map(this.state.activities, (activity, i) => { 
         return (
          <div key={ i }> 
           <input id={ `register-activity-${ i }` } 
            type="checkbox" 
            name="main_activity" checked={ !!activity.checked } 
            onChange={ (e) => this.toggleActivity(e, activity.id) } 
           /> 
           <label htmlFor={ `register-activity-${ i }` }>{ activity.name }</label> 
          </div> 
         ) 
        }) 
       } 
       </div> 
      </div> 
     ); 
    } 
} 

EDIT2 Ich spiele um und entschied onChange mit onClick REPLCE und jetzt bin ich in der Lage Klicken Sie auf das Kontrollkästchen, um auf toggleActivity zu klicken. Hat jemand eine Idee warum OnChange nicht feuert?

Antwort

0

Die Antwort auf meine Frage wurde on this SO post gefunden. Es stellt sich heraus, dass das Ereignis meines Labels onClick (hinter den Szenen von html/React, nicht selbst codiert) sprudelte bis zum Eltern, anstatt die Eingabe zu behandeln. Ich musste dem Label sagen, dass es aufhören soll, sich zu verbreiten, indem man onClick={ e => e.stopPropagation() } tut.

2

Ich glaube, Sie haben einen Fehler in Ihrer toggleActivity Funktion, Aktivitäten Array wird und versuchen, es zu konvertieren, um das Objekt, können Sie meine volle Lösung dieses Problems finden Sie hier: https://codesandbox.io/s/wqyolw50vl

toggleActivity(e, activityId) { 
    const { activities } = this.state; 

    const updated = activities.map(activity => { 
     if (activity.id === activityId){ 
     return { 
      ...activity, 
      checked: !activity.checked 
     } 
     } 

     return activity; 
    }) 

    this.setState({ activities: updated }); 
    } 
+0

Dank für diesen Fang. Aus irgendeinem Grund kann ich immer noch nicht herausfinden, was mein Label daran hindert, auf die Eingabe zu klicken. 'toggleActivity' feuert überhaupt nicht. Das Platzieren eines Debuggers an dem Anfang der Funktion führt nichts aus. –

+0

In Ihrem Beispiel wird der lokale Status nicht korrekt aktualisiert, daher gibt es kein neues Kontrollkästchen checked, https: // codesandbox.io/s/wqyolw50vl - funktionierendes Beispiel –

+0

Ich habe gerade mit Ihrem Beispiel in meiner Datei bearbeitet, entfernen Sie alle anderen Code und es funktioniert immer noch nicht für mich. ** Bearbeiten ** Auch in einem Akt der Verzweiflung habe ich Ihre Lösung innerhalb der App-Klasse vollständig in meine Lösung kopiert und trotzdem werden keine Klicks ausgelöst. –

0

Ich hatte das gleiche Problem. Es hat mich wahnsinnig gemacht, aber was mein Team und ich entdeckt haben, ist dass es einen Bug mit der htmlFor gibt, den Sie in der Dokumentation verwenden. Wir haben es aus unserer Checkbox-Prop entfernt und jetzt funktioniert es wie erwartet ohne seltsame Nebenwirkungen. Ich eröffne ein GH-Problem. Ich werde später mit dem Link bearbeiten/aktualisieren

Code, der nicht funktioniert hat:

<label htmlFor={`${label}-checkbox`} className={checked ? "checked data-filter-checkbox" : "data-filter-checkbox"} > 
    <input id={`${label}-checkbox`} type="checkbox" onChange={(event) => handleCheck(event)} value={label} name={label} checked={checked} /> 
    {label} 
    <span>{count}</span> 
</label> 

-Code ich jetzt bin mit:

<label className={checked ? "checked data-filter-checkbox" : "data-filter-checkbox"} > 
    <input id={`${label}-checkbox`} type="checkbox" onChange={(event) => handleCheck(event)} value={label} name={label} checked={checked} /> 
    {label} 
    <span>{count}</span> 
</label> 
+0

Großartig. Das Projekt, an dem ich gerade arbeitete, war das einzige, bei dem ich Checkboxen dynamisch erstellen musste. Daher würde ich gerne Fortschritte darin sehen. Wer weiß, vielleicht war es nur ein React 15 Fehler und wurde in 16 behoben. –

Verwandte Themen