2017-06-02 4 views
0

Ich habe eine Reaktion App wie:Pass Zustand Updater clickhandler in React

Main.js-

import React, { Component } from 'react'; 
import _ from 'underscore'; 

import ApplicationsButtons from '../components/ApplicationsButtons'; 


let applications_url = 'http://127.0.0.1:8889/api/applications' 


export default class Main extends Component { 

    constructor(props) { 
     super(props); 
     this.state = {applications: [], selected_app: 1}; 
     this.updateSelectedApp = this.updateSelectedApp.bind(this); 
    } 

    componentDidMount() { 
    let self = this; 
    $.ajax({ 
     url: applications_url, 
     method: 'GET', 
     success: function(data) { 
      console.log(data); 
      let objects = data.objects; 
      let apps = objects.map(function(object) { 
       return {name: object.name, id: object.id}; 
      }); 
      console.log(apps); 
      self.setState({applications: apps}); 
     } 
    }); 
    } 

    updateSelectedApp(id) { 
     this.setState({selected_app: id}); 
    } 

    render() { 

    return (
     <div> 
     {this.state.selected_app} 
     <ApplicationsButtons apps={this.state.applications} /> 
     </div> 
    ); 
    } 
} 

ApplicationsButtons.js-

import React, { Component } from 'react'; 


export default class ApplicationsButtons extends Component { 

    render() { 
    var buttons = null; 
    let apps = this.props.apps; 
    let clickHandler = this.props.clickHandler; 
    if (apps.length > 0) { 
     buttons = apps.map(function(app) { 
      return (<button key={app.id}>{app.name} - {app.id}</button>); 
      // return (<button onClick={clickHandler.apply(null, app.id)} key={app.id}>{app.name} - {app.id}</button>); 
     }); 
    } 

    return (
     <div> 
     {buttons} 
     </div> 
    ); 
    } 
} 

Ich möchte ein onClick die passieren Schaltflächen, die die aktuell ausgewählte App ändern. Irgendwie habe ich gerade meine erste Endlosschleife in React bekommen ("setState hat gerade 20000 mal gelaufen"). Anscheinend, als ich versuchte, den Event-Handler zu übergeben, der aufgerufen werden sollte, habe ich gesagt, dass ich ihn weiterhin anrufen soll.

Die onClick-Funktion sollte state.selected_app für die Komponente Main, basierend auf der id für die Schaltfläche, die geklickt wurde ändern.

+1

Vielleicht nicht verwandt, aber diese Linie hat Nebeneffekt: 'this.setState ({selected_app: id});'. Sollte 'this.setState ({... this.state, selected_app: id});' also 'applications' Array nicht gelöscht werden. – wesley6j

+0

Ich dachte, es ignoriert jetzt einfach die anderen Teile deines Staates, ich benutze die neuesten react v15 – codyc4321

+0

@ codyc4321 Sie haben Recht, 'setState' verwendet [' Object.assign'] (https://developer.mozilla.org/ de-DE/docs/Web/JavaScript/Referenz/Global_Objects/Object/zuweisen) unter der Haube, so dass Ihre 'setState' Zeile in Ordnung ist. – glhrmv

Antwort

2

Sie übergeben den Handler nicht als Prop. Hier ist, was Sie tun sollten:

render() { 
    return (
    <div> 
     {this.state.selected_app} 
     <ApplicationsButtons 
     apps={this.state.applications} 
     handleClick={this.updateSelectedApp} 
     /> 
    </div> 
); 
} 

Und in ApplicationButtons:

render() { 
    var buttons = null; 
    let apps = this.props.apps; 
    let clickHandler = this.props.handleClick; 
    if (apps.length > 0) { 
    buttons = apps.map(app => 
     <button key={app.id} onClick={() => clickHandler(app.id)}>{app.name} - {app.id}</button>); 
    ); 
    } 

    return (
    <div> 
     {buttons} 
    </div> 
); 
} 
+0

Ich war, das war nur mein Beispielcode. Aber das funktioniert, ich habe vergessen, die neue es6-Methode zu verwenden, die das für Sie bindet – codyc4321

+2

Sie können auch 'onClick = {clickHandler.bind (this, app.id)}}. – glhrmv