每个实例在渲染我的 ES6 React/Reflux 组件两次时接收事件
Each instance receive events when rendering my ES6 React/Reflux component twice
我有一个组件(执行文本输入)在另一个组件中渲染了两次。
当我在其中一个文本输入组件中按下一个键时,每个组件都会收到通知...
该组件采用类似 "14:30"
的时间字符串,并且应允许输入小时和分钟部分。
反流行动:
let TimeActions = Reflux.createActions([
'setHour',
'setMinute'
]);
回流混入:
let TimeMixin = {
init: function() {
this.listenToMany(TimeActions);
},
onSetHour(h) {
this.time.hour = h;
this.trigger(this.time);
},
onSetMinute(m) {
this.time.minute = m;
this.trigger(this.time);
}
};
React 组件:
export default class TimePicker extends React.Component {
constructor(props) {
super(props);
let parts = this.props.time.split(':'),
time = {
hour: parts[0],
minute: parts[1]
};
this.store = Reflux.createStore({
mixins: [ TimeMixin ],
time: time
});
this.state = time;
}
componentDidMount() {
this.unsubscribe = this.store.listen(this.onTimeChanged.bind(this));
}
componentWillUnmount() {
this.unsubscribe();
}
onTimeChanged(time) {
console.log('TIME SET TO', time);
this.setState(time);
}
render() {
let classes = classNames('time-picker');
return (
<div className={classes}>
<table>
<tbody>
<tr>
<td>
<input type="text" className="hour" maxLength="2"
value={this.state.hour}
onChange={this.onHourChanged} />
</td>
<td class="separator">:</td>
<td>
<input type="text" className="minute" maxLength="2"
value={this.state.minute}
onChange={this.onMinuteChanged} />
</td>
</tr>
</tbody>
</table>
</div>
);
}
onHourChanged(event) {
TimeActions.setHour($(this.getDOMNode()).val());
}
onMinuteChanged(event) {
TimeActions.setMinute($(this.getDOMNode()).val());
}
}
我从另一个 React 组件渲染 TimePicker
两次...
...
<TimePicker time={this.props.from} />
<TimePicker time={this.props.to} />
...
...并且在任何实例的分钟输入中键入 "01"
时,我得到以下日志:
TIME SET TO Object {hour: "08", minute: "01"}
TIME SET TO Object {hour: "12", minute: "01"}
知道我做错了什么吗?
这是因为您在组件的构造函数级别创建了两个商店。
您应该在组件外部创建商店,这样无论您的组件有一个还是数百万个实例,都只会存在一个。
我有一个组件(执行文本输入)在另一个组件中渲染了两次。
当我在其中一个文本输入组件中按下一个键时,每个组件都会收到通知...
该组件采用类似 "14:30"
的时间字符串,并且应允许输入小时和分钟部分。
反流行动:
let TimeActions = Reflux.createActions([
'setHour',
'setMinute'
]);
回流混入:
let TimeMixin = {
init: function() {
this.listenToMany(TimeActions);
},
onSetHour(h) {
this.time.hour = h;
this.trigger(this.time);
},
onSetMinute(m) {
this.time.minute = m;
this.trigger(this.time);
}
};
React 组件:
export default class TimePicker extends React.Component {
constructor(props) {
super(props);
let parts = this.props.time.split(':'),
time = {
hour: parts[0],
minute: parts[1]
};
this.store = Reflux.createStore({
mixins: [ TimeMixin ],
time: time
});
this.state = time;
}
componentDidMount() {
this.unsubscribe = this.store.listen(this.onTimeChanged.bind(this));
}
componentWillUnmount() {
this.unsubscribe();
}
onTimeChanged(time) {
console.log('TIME SET TO', time);
this.setState(time);
}
render() {
let classes = classNames('time-picker');
return (
<div className={classes}>
<table>
<tbody>
<tr>
<td>
<input type="text" className="hour" maxLength="2"
value={this.state.hour}
onChange={this.onHourChanged} />
</td>
<td class="separator">:</td>
<td>
<input type="text" className="minute" maxLength="2"
value={this.state.minute}
onChange={this.onMinuteChanged} />
</td>
</tr>
</tbody>
</table>
</div>
);
}
onHourChanged(event) {
TimeActions.setHour($(this.getDOMNode()).val());
}
onMinuteChanged(event) {
TimeActions.setMinute($(this.getDOMNode()).val());
}
}
我从另一个 React 组件渲染 TimePicker
两次...
...
<TimePicker time={this.props.from} />
<TimePicker time={this.props.to} />
...
...并且在任何实例的分钟输入中键入 "01"
时,我得到以下日志:
TIME SET TO Object {hour: "08", minute: "01"}
TIME SET TO Object {hour: "12", minute: "01"}
知道我做错了什么吗?
这是因为您在组件的构造函数级别创建了两个商店。
您应该在组件外部创建商店,这样无论您的组件有一个还是数百万个实例,都只会存在一个。