All:
I am pretty new to React and FLUX, when I tried to follow FLUX TodoMVC example and make a example, the problem is I need to know how to mkae the click on button group only update its color text, but not affect the other component's color text( right now, if I click either div1's or div2's, both colortexts will change, I just want to according text changes color.): I know the store design right now is not for two components, but let assume the store can maintain a color list for according components, the question is still "How can I know which component is clicked"
// 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"));
And the page:
// 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>
Assuming you update your store to save multiple colors:
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];
},
// ...
});
You need some way to identify which piece of data to update in the store. You could, for example, pass a property:
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"));
Then, when you dispatch the action, you pass along the key so the store knows what data to update:
setColor: function(color){
Dispatcher.dispatch({
type:"Change_Color",
data: {
colorKey: this.props.colorKey,
"color": color
}
});
},
Similarly, you'd look up the data in the appropriate store in ColorText
:
getColor: function(){
return TodoStore.getColor(this.props.colorKey);
},