React, single page
сабж делается из несинглпейджа (сейчас на каждую страницу свой питоновский шаблон, index.jsx с рендерингом и т.д. - рендеринг только клиентский, серверный не нужен)
По замыслу хочется один шаблон, в нем роутер. Для каждой страницы есть свои скрипты, свой рендеринг, и это все должно подгружаться при необходимости. т.е. открыли страницу - покрутился спиннер, все загрузилось и нарисовалось. Жмякнули ссылку перехода - покрутился спиннер рядом со ссылкой, догрузилось что надо, перерисовалось. Жмякнули одну ссылку а потом сразу другую (не дождавшись первую), должна нарисоваться страница по второй. Вот примерно такие кейсы, если упрощенно. какие тут бестпрактисы, как это всё красиво обстряпать? |
по реакту большого опыта нет
|
для React16.6 сделали lazy, читать тут - https://reactjs.org/blog/2018/10/23/react-v-16-6.html
раньше было так (есть другие аналоги): https://github.com/jamiebuilds/react-loadable ну и обычный роутер https://github.com/ReactTraining/react-router можно посмотреть React16.7 правда его еще в мастер не коммитили, там есть Hook'и, проще подключать мултипл-контекс, про state management - надо сначала посмотреть context - https://reactjs.org/docs/context.html делаешь классы в них хранишь данные, пишешь ф-ции, которые обрабатывают данные если этого мало смотрим redux+saga, или mobx итого: context + router + lazy |
спасибо, глянул.
lazy не совсем то - там предполагается, что при нажатии на ссылку старая верстка исчезает и показывается только то что в свойстве fallback, пока грузятся компоненты для новой страницы. А мне надо во время загрузки не затирать то что есть, просто показывать лоадер где-то сверху |
задача 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 или забить на это и продумать поведение приложения заранее... ) |
Alexandroppolus,
С поисковой оптимизацией все так же возникают проблемы. На днях общался с очень уважаемым в SEO сфере человеком, он подтвердил. |
в 17 версии обещают server side rendering из коробки )
|
Часовой пояс GMT +3, время: 02:11. |