// app.js.coffee
@App = React.createClass
childContextTypes: { app: React.PropTypes.object.isRequired }
getChildContext: ->
{ app: this }
componentWillMount: ->
history.replaceState(@state, '')
$(window).on 'popstate', (e) =>
@setState(e.originalEvent.state)
getDefaultProps: ->
{ view: 'Top', values: {} }
getInitialState: ->
@props
moveTo: (view, url, state) ->
state = { view: view.displayName, values: state)
@setState(state)
window.history.pushState(state, '', url)
render: ->
Child = window[@state.view]
`<div>
<Navigation />
<Child {...this.state.value} />
<Fotter />
</div>`
App をアプリケーション全体のラッパーにする。
実際に表示するコンポーネントは @state.view
に設定する。
実際のコンポーネントの props
に渡すものは @state.values
に入れる。
ページ遷移は @context.app.moveTo(User, '/users/1', id: 1)
のような感じ。
コンポーネント内で変更されたstateをhistoryに記憶したいことがある。
例えばapiで叩いた結果とか
その時は window.history.state.values
に入れてやる
search: (q, page = 1) ->
$.ajax("/search.json?q=#{q}&page=#{page}").done (res) =>
@setState(results: res)
# window.history.state ってどうやってコピーすんの
window.history.state.values.results = res
window.history.pushState(window.history.state, '', "/serach?q=#{q}&page=#{page}")
上記の例で results
が最初の状態の時に history.state
に無い場合、
検索後の状態から history.back
した時に resutls
が消えてくれない。
componentDidMount
で初期状態の state
を history.state.values
に入れる処理をしないといけない。
# app/helpers/application_helper.rb
def react_component(view, opts)
opts = {
view: view,
values: opts
}
super('App', opts)
end
これで = react_component 'Search', q: @q
みたいな感じで書ける