2016-05-13 3 views
0

Я начинаю реализовывать шаблон умного/немого компонента, где «немой» компонент ничего не знает об окружающей среде и получает все свои данные через реквизиты. Что вы делаете, когда немой компонент должен отправлять или изменять данные? Как он может общаться с внешним миром и все еще быть «глупым»?реагировать на умный/немой шаблон компонента для изменения данных

Вот мой основной пример, который я использую, чтобы определить этот шаблон. Если бы я должен был добавить событие onClick к компоненту MyTask, который обновил счетчик в БД, что бы обработало это событие?

// 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, 
} 

и приложение:

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

ответ

2

Вообще вы можете обрабатывайте это, передавая ссылки функций от ваших «умных» компонентов до ваших «немых» компонентов. Затем немой компонент не отвечает за реализацию какой-либо логики, связанной с этой функцией, просто говоря интеллектуальному компоненту «Я был нажат».

В этом случае внутри вашего класса TaskApp в app.jsx вы можете иметь ваш обработчик щелчка:

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

Затем пройти handleClick через свои компоненты в качестве опоры:

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

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

и выполнить его в компоненте MyTask при нажатии элемента списка:

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

Храните i что если функция handleClick() использует «это» вообще, вам нужно будет .bind (this) в вашей ссылке на функцию при ее передаче (или привязать ее в конструкторе/использовать стрелку жира ES6 функции).

EDIT: Примеры других способов связать «это», вы могли бы в конструкторе класса присвоить связанную функцию справки this.handleClick, так:

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

... 
... 
} 

Что позволяет вы должны использовать this.handleClick, как вы обычно ожидаете.

Или вы могли бы использовать ES6 функции жира со стрелками, которые сохраняют контекст «это», когда их называют:

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

Принятый ответ за более подробное объяснение. Спасибо! – Scott

+0

Можете ли вы показать пример двух разных привязок 'this', пожалуйста? Это будет очень тщательный ответ с этим дополнением. – Scott

+0

Добавил несколько дополнительных примеров связывания контекста с ответом. Ура! –

1

Предполагая, что TaskApp является смарт-компонент и MyList является немым компонент, это должно быть что-то вроде

Смарт Компонент

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

Тупой компонент

// 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

Вы можете передать функцию обратного вызова обработчика события в качестве опоры для MyTask:

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

И затем использовать его в MyTask:

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

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

+0

Поскольку три ответы очень похожи друг на друга в течение нескольких минут проводки, это кажется, популярный метод. Спасибо! – Scott

 Смежные вопросы

  • Нет связанных вопросов^_^