React-routerのBrowerHistoryを、constructor内で使うと、Warning: setState(...):が発生する謎を解いた

##Reactなんだか良くわからんWarning多すぎ問題

以下は /user(user.js) にアクセスした時に
currentUserがnullであれば（＝signinしていなければ)
/sign-in (SIGN_IN_PATH) に遷移しなさいという処理。

加えて、user/hogeページ（this.props.children)にアクセスした時も、
currentUserがnullじゃないかどうかを判断しましょうね、というコード。
（こちらは今回は蛇足です）

```js:user.js
class User extends Component {
  constructor(props) {
    super(props);
    this.state = {currentUser: null}
    //問題となる部分
    if (!this.props.currentUser){
      return browserHistory.push(CommonConstants.SIGN_IN_PATH);
    }
  }

....
  // /user であれば renderMyAccount を
  // /user/hoge であればそれをレンダリングする
  renderContent() {
    if (this.props.children) {
      return this.props.children;
    } else {
      return this.renderMyAccount();
    }
  }

  renderMyAccount() {
    const {t} = this.props;
    const user = this.state.currentUser;
    if (!user) {return}
    return (
      <div className='col-md-8 col-md-offset-2'>
        アカウントページをずらっと出力。
      </div>
    )
  }

  render() {
    return (
      <div className='row'>
        {this.renderContent()}
      </div>
    );
  }
}

```

しかしエラーがでる。

> Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

素直に読んでみると、
①renderの中でstateをアップデートしていないか？
②他のコンポーネントのconstructorの中で（略

###①render()内でstateをアップデートするのはなぜダメなのか？
[renderの中でsetStateを呼んではいけない理由](http://blog.itamaev2.com/entry/2016/11/06/201314)
> render時にstateが更新される=>stateが更新されるとrenderが実行される=>render時にstateが更新される=>stateが・・・・ということになり無限にrenderが実行されてしまっていた。

なるほど、、、しかし今回はこのケースではないです。

###②他のコンポーネントのconstructorの中でstateをアップデートするのはなぜダメなのか？
[What will happen if I use setState（） function in constructor of a Class in ReactJS or React Native?](http://stackoverflow.com/questions/34961853/what-will-happen-if-i-use-setstate-function-in-constructor-of-a-class-in-react)
[Ability to call setState in the constructor](https://github.com/facebook/react/issues/5342)

簡単に言えば、**非同期通信だから**らしい。

どういうことかといえば、stateは本来一つのコンポーネントに依存しているべきであって、受け渡したり、複数のコンポーネントで同時に使われるべきではないということ。
非同期通信が可能故に、２つのコンポーネントでstateが同時進行的に変わるのは好ましくないということでした。

###でも今回はstateの更新なんてしてないぞ？？
問題は今回のソースコードのconstructor内で、setState()を使っていないということでした。

原因はBrowserHistoryのpushメソッドにありました。
[React-routerの公式ドキュメント](https://github.com/reactjs/react-router-redux/blob/master/README.md)
[History関数の公式ドキュメント](https://github.com/mjackson/history/blob/master/README.md#navigation)

> Navigation

> history objects may be used programmatically change the current
> location using the following methods:

> history.push(path, [state])
> history.replace(path, [state])
> history.go(n)
> history.goBack()
> history.goForward()
> history.canGo(n) (only in createMemoryHistory)


というわけで、push,replaceどちらを使っても、stateを受け渡すことになってしまい、それがエラー文中のupdateに該当しているということでした。
（間違っていたら是非指摘していただきたいです。）

##解決策
**componentWillMountを使う**
[こちらを参照](http://qiita.com/kawachi/items/092bfc281f88e3a6e456)
[こちらも参照](https://facebook.github.io/react/docs/react-component.html
)
これだったら確実にrender前に実行できます。


``````js:user.js
class User extends Component {
  constructor(props) {
    super(props);
    this.state = {currentUser: null}
    //ここでは一度返す
    if (!this.props.currentUser) {return}
    UserAction.getUser((user) => {
      this.setState({currentUser: user});
    });

  //ここで呼び出す。
  componentWillMount() {
    if (!this.props.currentUser) {
      return browserHistory.push(CommonConstants.SIGN_IN_PATH);
    }
  }
}

....

  renderContent() {
    if (this.props.children) {
      return this.props.children;
    } else {
      return this.renderMyAccount();
    }
  }

```

componentWillMountはrender前に呼び出されるので重宝します。