railsContextがreact(redux)側に渡ってない?!

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー
SEGAさん、DIVAの筐体ください(ズザー

react関係の記事を斜め読みしている時に、ふと、自分のcomponentには「railsContext」が渡ってきていないことに気がつきました。

そういえば、HelloWorldアプリのコードを追ってるときに、_railsContextを握りつぶしている箇所があって、

あれ〜おかしいなあ〜なんか変だな〜

って思ったことを思い出しました。

該当箇所

client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx

1
2
3
4
5
6
7
const HelloWorldApp = (props, _railsContext) => {
return (
  <Provider store={configureStore(props)}>
    <HelloWorldContainer />
  </Provider>
);
}

うん。「_railsContext」が完全にスルーされてる

railsContextとは?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  host: "localhost",
  href: "http://localhost:3000/",
  httpAcceptLanguage: "ja,en-US;q=0.8,en;q=0.6",
  i18nDefaultLocale: "en",
  i18nLocale: "en",
  inMailer: false,
  location: "/",
  pathname: "/",
  port: 3000,
  scheme: "http",
  search: null,
  serverSide: false,
}

というような内容の、objectです。

react_componentは、このrailsContextをpropsと併せてComponentに渡してくれているんですが、こいつがHelloWorldAppでは完全に握りつぶされてしまっております。
HelloWorldAppを参考に組んでいる現アプリも、当然ながら握りつぶしている状況です。

今々の段階ではこの情報がないからと言ってすぐに困るわけではありませんが、 不安の芽は早めに摘んでおくことにします。

RailsContextが渡ってくるように調整する

そもそも握りつぶしているのがよくない!propsでひとまとめにすればええんやろ?
という超安易な発想で修正。

client/app/Routes.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { combineReducers } from 'redux';
import { routerStateReducer, ReduxRouter } from 'redux-router';
import { Provider } from 'react-redux';
import configureStore from './stores/store';
import routes from './routes/routes';
import railsContextReducer from './reducers/railsContextReducer';

const reducer = combineReducers({
  // railsContextに関するreducerを渡してあげる
  railsContext: railsContextReducer,
  router: routerStateReducer,
});

const Routes = (props, railsContext) => {
  return (
    // propsとrailsContextをマージして渡す
    <Provider store={configureStore(routes, reducer, {...props, railsContext})}>
      <ReduxRouter />
    </Provider>
  );
}

export default Routes;

client/app/reducers/railsContextReducer.jsx

1
2
3
4
5
6
// 現段階ではstateをそのまま返すでよい
const railsContextReducer = (state = {}) => {
  return state;
}

export default railsContextReducer;

client/app/containers/IndexPage.jsx

storeにrailsContextを混ぜたinitialStateを登録したので、stateから引っ張ってくることができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { Component } from 'react'
import { connect } from 'redux'

class IndexPage extends Component {
  render() {
    console.log(this.props.railsContext);
    return (
      <div>
        <a href="">I LOVE MINKA</a>
      </div>
    )
  }
}

const mapStateToProps = (state) => ({
  railsContext: state.railsContext,
});

export default connect(mapStateToProps)(IndexPage)

これで、railsContextへの参照も問題なさそうですね!
本来は、IndexPageを内包するコンポーネントを作ることになると思われるので、 親側から、子のpropsに差し込むようなコーディングをしてあげればなおよいでしょう。

よし!ご飯食べに行ってくる!