React Redux Rails
React.js & Redux & Ruby on Railsでserver-side rendering.
この記事はReact.js Advent Calendar 2015の10日目の記事であり、
仮想DOM/Flux Advent Calendar 2015の10日目の記事です. (欲張り.)
Source codeはReact Rails Example.
React Redux Rails
React.js
React.jsはFacebook製のJavaScriptのUI Library.
Viewの状態管理をさぼれる.
Redux
Reduxは今一番熱いFlux architecture frameworkで状態管理をatomitにする.
react-rails
Ruby on RailsにはReact.jsのserver-side renderingを容易にするGemがある.
<%= react_component('HelloMessage', name: 'John') %>
<!-- becomes: -->
<div data-react-class="HelloMessage" data-react-props="{"name":"John"}"></div>
こんな感じにViewにReact.jsのComponentを埋め込むことができる.
react_component
の3つ目の引数として {prerender: true}
を渡すだけで、server-side renderingができる.
<%= react_component('HelloMessage', {name: 'John'}, {prerender: true}) %>
<!-- becomes: -->
<div data-react-class="HelloMessage" data-react-props="{"name":"John"}">
<h1>Hello, John!</h1>
</div>
Try
これらを合わせて、Reduxで状態管理をして、ReactでComponentを組み立て、Ruby on Railsでserver-side renderingをしてみた.
BaseのAppはReduxのBasic tutorialになっているtiny todo app.
<%= react_component('Root', {presetTodos: @todos}, {prerender: true}) %>
app/views/todos/index.html.erb
とRuby on RailsのViewに埋め込むことにより、初回は server-side renderingで @todos
を props
に渡して componentDidMount
でDataをsetし、
それ以外で Root
をrenderした時は componentDidMount
でDataをfetchする.
(今回のExampleではこの遷移は実装していないが、 {presetTodos: @todos}
をはずぜばこの挙動となる.)
componentDidMount() {
const { dispatch, presetTodos } = this.props;
if (presetTodos) {
dispatch(setTodos(presetTodos));
} else {
dispatch(fetchTodos());
}
}
app/assets/javascripts/containers/App.js
軽くポイントを掻い摘む.
- JavaScriptのLibrary管理はnpmでbrowserify-railsを使ってBabelでbuildした.
application.js
は//= require react_ujs
と//= require components
のみ. (app/assets/javascripts/application.js)
- Babel 6だとDecorationが未supportだったため、Babel 5を使用した. (Implement new decorator proposal when finalized)
- ReduxでAsync.
詳しくはSourceに. 質問があればTwitterで #Rudolph_Miller に聞いて下さい.
意外とすんなり書け、すんなり動いたので、どこかで実戦投入したいと思う.