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
コードレビューを制するチームがソフトウェアデリバリーのフローを制す / Beyond Code Review: Distributing Its Responsibilities Across the SDLC
mtx2s
4
1.3k
ブロックチェーン / Blockchain
ks91
PRO
0
110
DevOps Agentで始めるAWS運用 〜フロンティアエージェントが変える運用の現場〜
nyankotaro
1
320
社内 AI エージェント Synapse と セマンティックレイヤーの育て方
hiroakis
0
410
非定型業務をAI slackbotで自動化する ~ 社内要望を自動壁打ちするbotを作った ~/automating-ad-hoc-work-with-ai-slackbot
shibayu36
0
400
新規ゲーム開発におけるAI駆動開発のリアル
202409e2
0
2.9k
チームで実践する AI-DLC 思考の軌跡を残すチェックポイント設計
belongadmin
0
3k
Snowflakeと仲良くなる第一歩
coco_se
2
190
美味しいスイスチーズを作ろう🧀🐭
taigamikami
1
260
LLMと共に進化するプロセスを目指して
ymatsuwitter
12
3.6k
AIプラットフォームを運用し続けるための可観測性
tanimuyk
4
1.2k
EventBridge Connection
_kensh
5
660
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Ethics towards AI in product and experience design
skipperchong
2
300
Google's AI Overviews - The New Search
badams
0
1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Writing Fast Ruby
sferik
630
63k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
380
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Mobile First: as difficult as doing things right
swwweet
225
10k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Building AI with AI
inesmontani
PRO
1
1.1k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
390
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/