Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Redux and React Server Rendering
Search
hui.liu
April 10, 2016
Technology
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Redux and React Server Rendering
hui.liu
April 10, 2016
More Decks by hui.liu
See All by hui.liu
How to build an online IDE with React
hulufei
0
540
利用Grunt打造前端工作流
hulufei
5
1.2k
Other Decks in Technology
See All in Technology
OPENLOGI Company Profile for engineer
hr01
1
75k
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
500
AI時代におけるテストの基礎の再定義 / Rethinking the Fundamentals of Testing in the AI Era
mineo_matsuya
14
5.4k
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
2
1k
Devsumi 2026 Summer 人もAIも使える共通基盤を事業の加速装置にする~デザインシステム運用に学ぶ組織レバレッジ~ 渡辺 凌央
legalontechnologies
PRO
1
300
書籍セキュアAPIについて
riiimparm
0
320
事業成長とAI活用を止めないデータ基盤アーキテクチャの設計思想
hiracky16
0
700
インシデント事例と パッケージの全量解析に学ぶ ソフトウェアサプライチェーンの守り方 / supply-chain-attack-defense
flatt_security
0
1k
MCPをつなげて作る組織横断のAIエージェント基盤
tsubakimoto_s
0
140
AI時代におけるエンジニアの新たな役割──FDEとクオリアの探求/登壇資料(戸井田 裕貴)
hacobu
PRO
0
380
アップデートで何が変わった?デモで学んで使いこなすIBM Bob2.0
muehara
0
250
2年前に削除したPHPクラスが、 ある日突然決済をエラーにした
ykagano
1
820
Featured
See All Featured
Designing Experiences People Love
moore
143
24k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
340
Believing is Seeing
oripsolob
1
170
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
310
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
420
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
230
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
620
We Are The Robots
honzajavorek
0
280
Why Our Code Smells
bkeepers
PRO
340
58k
The browser strikes back
jonoalderson
0
1.4k
Transcript
Redux Ө React ๐ۓ ᒒວ
ڝᬄ (@hulufei)
Why Server Rendering • Single Page Application (SPA) • Search
Engine Indexability (SEO)
Universal JavaScript Server Browser SPA Rendering
–Nick Dreckshage “react made it extremely easy.”
React Virtual DOM Server Browser SPA <App /> <div>…</div> renderToString()
UI Җ f(state)
None
– reactjs/redux “Redux is a predictable state container for JavaScript
apps.”
Redux Basic • Action • Reducer • Store
// Default function actionCreator() { return { type: 'ACTION_TYPE_CONSTANT', payload:
'payload' } } Action { type: ‘TYPE_CONSTANT’, payload: payload } thunk middleware promise middleware // Thunk function actionCreator() { return (dispatch) => { dispatch({ type: 'ACTION_TYPE_CONSTANT', payload: 'xx' }) // Async operation } } // Promise function actionCreator() { return { type: 'ACTION_TYPE_CONSTANT', payload: Promise.resolve(‘payload') } }
Reducer function reducer(state, action) { switch(action.type) { case 'ACTION_TYPE_CONSTANT': //
Update state return newState; default: return state; } } (previousState, action) => newState
Store import { createStore } from 'redux' import rootReducer from
'./reducers' let store = createStore(rootReducer) ӞӻଫአํӬՐํӞӻ Store // store.getState() ᬬࢧ State ᇫா // store.dispatch(action) ݎ reducer ๅෛ State // store.subscribe(listener) ፊލ State ๅෛ
Data Flow • action ฎӞӻ۱ތ { type, payload } ጱ
• reducer ڍහ᭗ᬦ store.dispatch(action) ݎ • reducer ڍහളݑ (state, action) ӷӻ݇හ • reducer ڍහڣෙ action.type ᆐݸ॒ቘଫጱ action.payload හഝๅ ෛᇫா҅ᬬࢧӞӻෛጱ state • store.subscribe(listener) ፊލ state ๅෛ
react-redux // index.js import { render } from 'react-dom'; import
{ Provider } from 'react-redux'; import App from './app'; render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); // app.js class App extends Component { ... } export default connect( mapStateToProps, mapDispatchProps )(App); <Provider /> connect const mapStateToProps = (state) => ({ propA: stateA, … }) const mapDispatchProps = (dispatch) => ({ propDoAction: (args) => dispatch(actionCreator(args)) ... })
Server Rendering Server Browser SPA UI = f(state) initialState Rendering
Server Rendering import { renderToString } from 'react-dom/server'; function renderFullPage(html,
initialState) { return ` <!DOCTYPE html> ... <div id=“root”>${html}</div> <script> window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}; </script> ... ` } app.use((req, res) => { store.dispatch(fetchActionCreator()) .then(_ => { const html = renderToString( <Provider store={store}> <App /> </Provider> ); res.end(renderFullPage(html, store.getState())); }); }); }); Browser SPA const initialState = window.__INITIAL_STATE__; const store = createStore(rootReducer, initialState); Browser SPA componentDidMount() { store.dispatch(fetchActionCreator()); }
None
react-router (Client) import { Route, IndexRoute } from 'react-router'; const
Container = (props) => <div>{props.children}</div>; const routes = ( <Route path="/" component={Container} > <IndexRoute component={App} /> <Route path=“path/:other” component={Other} /> </Route> ); export default routes;
react-router (Server) import { renderToString } from 'react-dom/server' import {
match, RouterContext } from 'react-router' import routes from './routes' function renderFullPage(html, initialState) { … } app.use((req, res) => { match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { if (error) { res.status(500).send(error.message) } else if (redirectLocation) { res.redirect(302, redirectLocation.pathname + redirectLocation.search) } else if (renderProps) { store.dispatch(fetchActionCreator()) .then(_ => { const html = renderToString( <Provider store={store}> <RoutingContext {...renderProps} /> </Provider> ); res.end(renderFullPage(html, store.getState())); }); } else { res.status(404).send('Not found') } }) }) match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { import routes from './routes' <RoutingContext {...renderProps} /> Browser SPA <Route path="/" component={Container} > <IndexRoute component={App} /> <Route path=“path/:other” component={Other} /> </Route>
– reactjs/react-router “Knowing what code should run on the server
and on the client is important to using React in a universal app.”
Client or Server • componentDidMount() Invoked once, only on the
client (not on the server) • <Link /> or <a /> • isomorphic-fetch
Server Consistent function renderFullPage(html, initialState) { return ` <!DOCTYPE html>
... <div id=“root”>${html}</div> ... ` } Browser document.addEventListener('DOMContentLoaded', () => { render(<App />, document.getElementById('root')); }); <div id=“root”></div> <div id=“root”>${html}</div> document.getElementById('root')
Demo https://src.coding.net/