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

时间:2015-12-01 17:09:22

标签: reactjs reactjs-flux

所有

我对React和FLUX很新,当我尝试关注FLUX TodoMVC example并举个例子时,问题是我需要知道如何点击按钮组只更新它的颜色文本,但不影响其他组件的颜色文本(现在,如果我点击div1÷或div2' s,两个colortexts都会改变,我只想根据文本更改颜色。): 我知道现在的商店设计不适用于两个组件,但我们假设商店可以维护相应组件的颜色列表,问题仍然是" 如何知道点击了哪个组件"

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

1 个答案:

答案 0 :(得分:1)

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

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