反应智能/哑元件模式以改变数据

时间:2016-05-13 14:01:15

标签: meteor reactjs meteor-react

我开始实现智能/哑元组件模式,其中“哑”组件对其环境一无所知,并通过道具接收所有数据。当哑组件必须提交或更改数据时,您会怎么做?它如何与外界沟通并仍然“愚蠢”?

这是我用来计算这个模式的基本例子。如果我要将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:

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

3 个答案:

答案 0 :(得分:2)

一般来说,您可以通过传递“智能”功能参考来处理此问题。组件直到你的哑巴&#39;组件。然后,愚蠢的组件不负责实现与该功能相关的任何逻辑,只是告诉智能组件“我已被点击”。

在这种情况下,app.jsx中的TaskApp类内部可以有你的点击处理程序:

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

请记住,如果handleClick()函数正在使用&#39;这个&#39;在你传递它时,你需要在你的函数引用上绑定(这个)(或者在构造函数中绑定它/使用ES6胖箭头函数)。

编辑:有关绑定&#39;的其他方法的示例,您可以在类的构造函数中将绑定函数分配给this.handleClick引用,因此:

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

...
...
}

允许你使用this.handle点击你通常期望的方式。

或者你可以使用ES6胖箭头功能,它保留了这个&#39;这个&#39;当他们被召唤时:

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

答案 1 :(得分: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,
}

答案 2 :(得分: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