2016-05-13 14 views
0

Ich fange an, die Smart/Dumme-Komponente-Muster zu implementieren, wo die "dumme" Komponente nichts über ihre Umgebung weiß und alle ihre Daten durch Requisiten erhält. Was tun Sie, wenn die dumme Komponente Daten übermitteln oder ändern muss? Wie kann es mit der Außenwelt kommunizieren und trotzdem "dumm" sein?reagieren Smart/dumm Komponente Muster für die Änderung von Daten

Hier ist mein grundlegendes Beispiel, das ich verwende, um dieses Muster herauszufinden. Wenn ich hinzufügen und onClick Ereignis zu der MyTask Komponente, die einen Zähler in der DB aktualisiert, was würde dieses Ereignis behandeln?

// components/MyList.jsx 

import React from 'react'; 

export default class MyList extends React.Component { 
    render() { 
     return(
      <div> 
       <h3>{this.props.listName}</h3> 
       <ul> 
        {this.props.tasks.map((task) => (
         <MyTask key={task.id} task={task} /> 
        ))} 
       </ul> 
      </div> 
     ); 
    } 
} 
MyList.propTypes = { 
    listName: React.PropTypes.string.isRequired, 
    tasks: React.PropTypes.array.isRequired, 
} 



export class MyTask extends React.Component { 
    render() { 
     return (
      <li>{this.props.task.text}</li> 
     ); 
    } 
} 
MyTask.propTypes = { 
    task: React.PropTypes.object.isRequired, 
} 

und die App:

// app.jsx 

import React from 'react'; 
import MyList from './components/MyList.jsx' 


export class TaskApp extends React.Component { 

    getList() { 
     return('Today Stuff'); 
    } 

    getTasks() { 
     return([ 
      {id: 1, text: 'foo'}, 
      {id: 2, text: 'diggity'}, 
      {id: 3, text: 'boo'}, 
      {id: 4, text: 'bop'} 
     ]); 
    } 

    render() { 
     return (
      <MyList listName={this.getList()} tasks={this.getTasks()} /> 
     ); 
    } 
} 

Antwort

2

Sie Generell können Behandeln Sie dies, indem Sie Funktionsreferenzen von Ihren "intelligenten" Komponenten an Ihre "dummen" Komponenten übergeben. Die dumme Komponente ist dann nicht dafür verantwortlich, irgendeine mit der Funktion verknüpfte Logik zu implementieren, sondern teilt der intelligenten Komponente "Ich wurde geklickt" nur mit.

//app.jsx 
... 
handleClick() { 
    // Update the DB counter by 1 
} 
... 
render() {} 

Dann passieren handle durch Ihre Komponenten als Stütze:

<MyList listName={this.getList()} tasks={this.getTasks()} handleClick={this.handleClick} /> 

<MyTask key={task.id} task={task} handleClick={this.props.handleClick} /> 

und führen Sie es

In diesem Fall innerhalb Ihrer TaskApp Klasse in app.jsx Sie Ihre Click-Handler haben könnte in der MyTask-Komponente, wenn auf ein Listenelement geklickt wird:

<li onClick={this.props.handleClick}>{this.props.task.text}</li> 

Keep i Beachten Sie, dass, wenn die Funktion handleClick() überhaupt von 'this' Gebrauch macht, Sie Ihre Funktionsreferenz beim Übergeben binden müssen (oder binden Sie sie im Konstruktor/verwenden Sie den dicken ES6-Pfeil) Funktionen).

EDIT: Beispiele für die anderen Wege zu binden ‚dies‘, Sie im Konstruktor Ihrer Klasse die gebundene Funktion, um Ihre this.handleClick Referenz, so zuordnen konnte:

export default class TaskApp extends React.Component { 
    constructor(props) { 
    super(props); 
    this.handleClick = this.handleClick.bind(this); 
    } 

... 
... 
} 

Welche erlaubt Sie verwenden this.handleKlicken Sie auf die Art, wie Sie normalerweise erwarten würden.

Oder Sie könnten ES6 Fett Pfeil-Funktionen verwenden, die den Kontext von ‚this‘ erhalten, wenn sie aufgerufen werden:

<MyList 
    listName={this.getList()} 
    tasks={this.getTasks()} 
    handleClick={() => this.handleClick} /> 
+0

Akzeptierte Antwort für ein bisschen mehr in der Erklärung. Vielen Dank! – Scott

+0

Können Sie bitte ein Beispiel für die zwei verschiedenen Bindungen von 'this' zeigen? Dies wäre eine sehr gründliche Antwort mit diesem Zusatz. – Scott

+0

Einige zusätzliche Beispiele für den Bindungskontext zur Antwort hinzugefügt. Prost! –

1

Unter der Annahme, dass TaskApp die Smart-Komponente und MyList ist die stumme Komponente, sollte es so etwas wie

Smart Component

// app.jsx 

import React from 'react'; 
import MyList from './components/MyList.jsx' 


export class TaskApp extends React.Component { 

    getList() { 
     return('Today Stuff'); 
    } 

    getTasks() { 
     return([ 
      {id: 1, text: 'foo'}, 
      {id: 2, text: 'diggity'}, 
      {id: 3, text: 'boo'}, 
      {id: 4, text: 'bop'} 
     ]); 
    } 
    handleClick(task){ 
     // update the db here 
    } 

    render() { 
     return (
      <MyList listName={this.getList()} tasks={this.getTasks()} 
       onClick={this.handleClick}/> 
     ); 
    } 
} 

sein Dumb Komponente

// components/MyList.jsx 

import React from 'react'; 

export default class MyList extends React.Component { 
    render() { 
     return(
      <div> 
       <h3>{this.props.listName}</h3> 
       <ul> 
        {this.props.tasks.map((task) => (
         <MyTask onClick={() => this.props.onClick(task)} 
          key={task.id} task={task} /> 
        ))} 
       </ul> 
      </div> 
     ); 
    } 
} 
MyList.propTypes = { 
    listName: React.PropTypes.string.isRequired, 
    tasks: React.PropTypes.array.isRequired, 
} 



export class MyTask extends React.Component { 
    render() { 
     return (
      <li onClick={this.props.onClick}>{this.props.task.text}</li> 
     ); 
    } 
} 
MyTask.propTypes = { 
    task: React.PropTypes.object.isRequired, 
} 
1

Sie können die Event-Handler Callback als Stütze zu MyTask passieren:

<MyTask onClick={this.handleTaskClick.bind(this)} ... /> 

Und es dann in MyTask verwenden:

<li onClick={this.props.onClick}>...</li> 

See: https://facebook.github.io/react/docs/tutorial.html#callbacks-as-props

+0

Da es innerhalb weniger Minuten der Entsendung, diese zueinander drei Antworten waren sehr ähnlich scheint scheint die beliebte Methode zu sein. Vielen Dank! – Scott