考虑以下几乎相同的两个片段。
区别在于:
- 第一个用于
setTimeout()
触发事件 - 第二个在按钮被点击时触发事件
如果您检查控制台,您会看到 Snippet 1 中的最后两行是:
App rendering 1 folder(s)
Observed js
在片段 2 中是:
Observed js
App rendering 1 folder(s)
问题:为什么顺序颠倒了?
代码段 1:setTimeout() 触发器
class App extends React.Component {
constructor() {
super();
this.events$ = new Rx.Subject();
this.eventsByName$ = this.events$.groupBy(e => e.name);
this.state = {};
setTimeout(() => {
console.log('Emitting event');
this.events$.next({
type: 'ADD_FOLDER',
name: 'js',
permissions: 400
});
}, 1000);
}
componentDidMount() {
this.eventsByName$.subscribe(folderEvents$ => {
const folder = folderEvents$.key;
console.log(`New stream for "${folder}" created`);
folderEvents$.subscribe(e => {
console.log(`Observed ${e.name}`);
});
this.setState({
[folder]: folderEvents$
});
});
}
render() {
const folders = Object.keys(this.state);
console.log(`App rendering ${folders.length} folder(s)`);
return (
<div>
{
folders.map(folder => (
<div key={folder}>
{folder}
</div>
))
}
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
<head>
<script src="https://unpkg.com/rxjs@5.2.0/bundles/Rx.js"></script>
<script src="https://unpkg.com/react@15.4.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.4.2/dist/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
</body>
代码段 2:按钮触发器
class App extends React.Component {
constructor() {
super();
this.events$ = new Rx.Subject();
this.eventsByName$ = this.events$.groupBy(e => e.name);
this.state = {};
}
componentDidMount() {
this.eventsByName$.subscribe(folderEvents$ => {
const folder = folderEvents$.key;
console.log(`New stream for "${folder}" created`);
folderEvents$.subscribe(e => {
console.log(`Observed ${e.name}`);
});
this.setState({
[folder]: folderEvents$
});
});
}
onClick = () => {
console.log('Emitting event');
this.events$.next({
type: 'ADD_FOLDER',
name: 'js',
permissions: 400
});
};
render() {
const folders = Object.keys(this.state);
console.log(`App rendering ${folders.length} folder(s)`);
return (
<div>
<button onClick={this.onClick}>
Add event
</button>
<div>
{
folders.map(folder => (
<div key={folder}>
{folder}
</div>
))
}
</div>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
<head>
<script src="https://unpkg.com/rxjs@5.2.0/bundles/Rx.js"></script>
<script src="https://unpkg.com/react@15.4.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.4.2/dist/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
</body>