Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Redux and React Server Rendering
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
550
利用Grunt打造前端工作流
hulufei
5
1.2k
Other Decks in Technology
See All in Technology
Railsのように考える: See through the Master
snoozer05
PRO
5
1.3k
C#未経験の僕がAIに読めるコードを書かせるまで
maguroalternative
0
260
エージェントはローカル、検証はMicroVM — Lambda MicroVMsでつくるServerless CI
fujioka6789
3
760
AIエージェントを最高のパートナーに育てる方法|評価と判断軸を育てる5つのステップ
koichiaoki
1
160
AIに任せた品質は、誰が見立てるのか - AI時代のテストマネジメント
nakanao
3
2.9k
AIエージェントの権限管理 3: Agentic RAG の Fine grained access control 編
ren8k
1
240
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
570
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
140
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
3
530
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.7k
ScotSecure West 2026 - Glasgow
raybugg
0
160
Cloudflare Workers 向けアプリを C# で構築する ~WASM Native AOT への道~
nenonaninu
1
1.4k
Featured
See All Featured
Believing is Seeing
oripsolob
1
220
It's Worth the Effort
3n
188
29k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
RailsConf 2023
tenderlove
30
1.6k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
610
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
How to Think Like a Performance Engineer
csswizardry
28
2.8k
A Tale of Four Properties
chriscoyier
163
24k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
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/