在 React 中添加到同一个侦听器时如何区分不同的组件

How to tell different component when add to same listener in React

全部:

我是 React 和 FLUX 的新手,当我尝试遵循 FLUX TodoMVC example 并举个例子时,问题是 我需要知道如何点击按钮组只更新它的颜色文本,但不影响其他组件的颜色文本(现在,如果我点击 div1 或 div2,两个颜色文本都会改变,我只想根据文本改变颜色。): 我知道现在的商店设计不是针对两个组件的,但假设商店可以为相应的组件维护一个颜色列表,问题仍然是“我怎么知道点击了哪个组件

// app.js
var Dispatcher = new (require("./Dispatcher"));
var assign = require("object-assign");
var React = require("react");
var ReactDOM = require("react-dom");

var EventEmitter = require("events");



var TodoStore = assign({}, EventEmitter.prototype, {
    color: "black",
    dispatcherIndex: Dispatcher.register(function(payload){
        var type = payload.type;
        var data = payload.data;
        switch(type){
            case "Change_Color": {
                TodoStore.color = data.color;
                TodoStore.emitChange();
                break;
            }
        }
    }),
    getColor: function(){
        return this.color;
    },
    emitChange: function(){
        this.emit("CHANGE");
    },
    addChangeListener: function(callback){
        this.on("CHANGE", callback);
    },
    removeChangeListener: function(callback){
        this.removeListener("CHANGE", callback)
    }
});

var ColorButtonGroup = React.createClass({
    setColor: function(color){
        Dispatcher.dispatch({
            type:"Change_Color",
            data: {
                "color": color
            }
        });
    },
    render: function(){
        return (
            <div>
            <button style={{color:"red"}} onClick={this.setColor.bind(this,"red")}>RED</button>
            <button style={{color:"green"}} onClick={this.setColor.bind(this,"green")}>GREEN</button>
            <button style={{color:"blue"}} onClick={this.setColor.bind(this,"blue")}>BLUE</button>
            </div>
        );
    }
});

var ColorText = React.createClass({
    getInitialState: function(){
        return {
            style: {
                color: "black"
            }
        }
    },
    render: function(){
        return (
            <div style={this.state.style}>Color is: {this.state.style.color}</div>
        );
    },
    componentDidMount: function(){
        TodoStore.addChangeListener(this._onChange.bind(this));
    },
    componentWillUnmount: function(){
        TodoStore.removeChangeListener(this._onChange.bind(this));
    },
    getColor: function(){
        return TodoStore.getColor();
    },
    _onChange: function(){
        this.setState({
            style: {
                color:this.getColor()
            }
        });
    }
});

ReactDOM.render((<div>
    <ColorButtonGroup></ColorButtonGroup>
    <ColorText></ColorText>
    </div>), 
document.getElementById("div1"));
ReactDOM.render((<div>
    <ColorButtonGroup></ColorButtonGroup>
    <ColorText></ColorText>
    </div>), 
document.getElementById("div2"));

以及页面:

// bundle is transpiled+browserify app.js and dependecies 
<html>
<head>
    <title>LEARN FLUX</title>
</head>
<body>
    <div id="div1"></div>
    <div id="div2"></div>
</body>
    <script src="bundle.js"></script>
</html>

假设您更新商店以保存多种颜色:

var TodoStore = assign({}, EventEmitter.prototype, {
    colors: {},
    dispatcherIndex: Dispatcher.register(function(payload){
        var type = payload.type;
        var data = payload.data;
        switch(type){
            case "Change_Color": {
                TodoStore.colors[data.colorKey] = data.color;
                TodoStore.emitChange();
                break;
            }
        }
    }),
    getColor: function(key){
        return this.colors[key];
    },
    // ...
});

您需要一些方法来确定要在商店中更新的数据。例如,您可以传递 属性:

ReactDOM.render((<div>
    <ColorButtonGroup colorKey="1" />
    <ColorText colorKey="1" />
    </div>), 
document.getElementById("div1"));
ReactDOM.render((<div>
    <ColorButtonGroup colorKey="2" />
    <ColorText colorKey="2" />
    </div>), 
document.getElementById("div2"));

然后,当您分派操作时,您会传递密钥,以便商店知道要更新哪些数据:

setColor: function(color){
    Dispatcher.dispatch({
        type:"Change_Color",
        data: {
            colorKey: this.props.colorKey,
            "color": color
        }
    });
},

同样,您可以在 ColorText 中的相应存储中查找数据:

getColor: function(){
    return TodoStore.getColor(this.props.colorKey);
},