задача very complex, ) если не знать куда жать...
вот тебе мини прожект:
.babelrc
{
"presets": [
"env",
"react",
"es2015",
"stage-0"
],
"plugins": [
"transform-class-properties"
]
}
package.json
{
"name": "ttttest",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"babel-core": "^6.26.3",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"express": "^4.16.4",
"parcel-bundler": "^1.10.3",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1"
}
}
server.js
const path = require('path')
const Bundler = require('parcel-bundler')
const bundler = new Bundler(path.join(__dirname, 'src', 'index.html'), {})
const express = require('express')
const app = express()
const server = require('http').Server(app)
// const io = require('socket.io')(server)
const server_messages = [
{ id: 1, title: 'message1' },
{ id: 2, title: 'message2' }
]
app.use(express.static(path.join(__dirname, 'public')))
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})
app.get('/data', function (req, res) {
setTimeout(() => res.json(server_messages), 5000)
})
// io.on('connection', function (socket) {
// })
app.use(bundler.middleware())
server.listen(2999, () => console.log('started at http://localhost:2999'))
src/index.html
<html>
<head></head>
<body>
<div id="app"></div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import createBrowserHistory from "history/createBrowserHistory";
import { Router, Route, Link } from "react-router-dom"
const browserHistory = createBrowserHistory()
class Index extends React.Component {
state = {
loading: false
}
render() {
return <React.Fragment>
<h2>Home</h2>
<button onClick={() => {
this.setState({ loading: true })
fetch('/data').then(r => r.json()).then(data => this.setState({ data, loading: false }))
}}>getData</button>
<button onClick={() => console.log('cancel')}>cancel request</button>
{this.state.loading && <div>loading...</div>}
{this.state.data && this.state.data.map(d => <div>{`${d.id} - ${d.title}`}</div>)}
</React.Fragment>
}
}
const About = () => <h2>About</h2>
const Users = () => <h2>Users</h2>
ReactDOM.render(
<Router history={browserHistory}>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about/">About</Link>
</li>
<li>
<Link to="/users/">Users</Link>
</li>
</ul>
</nav>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
<Route path="/users/" component={Users} />
</div>
</Router>,
document.getElementById('app')
)
осталось сделать fetch cancelable:
https://developers.google.com/web/up...bortable-fetch
https://stackoverflow.com/questions/...-fetch-request
или использовать
https://github.com/axios/axios
у него есть cancel
или забить на это и продумать поведение приложения заранее... )