フロントエンド(React関係)備忘録

Reactに関連したものの脳内整理用

# React

- 宣言的記述
    - 対義: 手続き的記述
        - 例: jQueryのイベントベースの処理
    - 読みやすい(何がしたいものか明瞭になる)
- コンポーネント
    - ページの構成要素をコンポーネントというパーツに分けられる
    - 状態管理が容易
    - 再利用しやすい
- SPA想定
    - Reactはページの差分更新をコンポーネントを使って行いやすい

### どんな感じか

```js:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
```

```jsx:app.jsx
import React, { Component } from 'react';
import './App.css';
import Form from './Form';

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      // ...
    }

    render() {
      return (
        <div>
          <Form />
          // ...
        </div>
      )
    }
  }
}
export default App;
```

こんな感じでComponentを指定の場所にrenderする。
JSXを使うのでwebpackなどのbuildを通す

# Redux

- FluxというアーキテクチャパターンをReact用に提供したもの
    - [Action] → [Dispatcher] → [Store] → [View]
    - 利用側とストアとの関係は参照だけ
    - 更新したい場合はDispatcherを通すというルールによって更新処理を集約する
    - 更新処理が散らばっていないのでデータの状態管理がしやすい
- Reduxは
    - ただひとつのStoreをページ内で利用する
    - Dispatcherの代わりにStoreのfunctionに更新処理を集約

### どんな感じか

```jsx:index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import Reducer from './reducers/index.js'
import { Provider } from 'react-redux';
import App from './App';

const store = createStore(Reducer)

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
```

```jsx:store.js
import { combineReducers, createStore, compose, applyMiddleware} from 'redux'
import { Reducer, State } from './reducer'
import thunk from "redux-thunk"

const initData = {
  // ...
}

export function AppReducer(state = initData, action) {
  switch (action.type) {
    case '...';
      // return ...;
    case '...';
      // return ...; 
  }
}
const store = createStore(
    combineReducers<AppState>({
      state: Reducer
    }),
    storeEnhancers(applyMiddleware(thunk))
)

export default createStore(AppReducer);
```


```jsx:App.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import './App.css';
import Form from './Form';

const mapStateToProps = (state) => {
  return {
    // ...
  }
}

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      // ...
    }

    render() {
      return (
        <div>
          <Form />
          // ...
        </div>
      )
    }
  }
}

export default App = connect(mapStateToProps)(App); 
```

```jsx:Form.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {  }

const mapStateToProps = (state) => {
  return {
    // ...
  }
}

class Form extends Component {
  constructor(props) {
    super(props)
    this.state = {
      // ...
    }

    doSubmit(e) {
      let action = ...
      this.props.dispatch(action);
    }

    render() {
      return (
        <div>
          // ...
        </div>
      )
    }
  }
}

export default App = connect(mapStateToProps)(App); 
```

# Next.js

- Reactベースのフレームワーク
    - HTMLやassetsを返すnodejsのサーバー
- 「バンドル」「コンパイル」「ルーティング」などの機能を有している
- サーバーサイドレンダリングや静的サイトジェネレータとして機能する
- SSR(サーバーサイドレンダリング) 
 - https://qiita.com/uehaj/items/1b7f0a86596353587466#%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AAssrnextjs%E3%81%AA%E3%81%A9%E3%81%AE%E5%8B%95%E4%BD%9C

> ブラウザが初期ページを読み込むタイミングで、サーバ側のNode.jsでReactアプリが実行され、初期HTMLを生成(SSR)します。ブラウザがそれを読み込んで初期表示し、引き続きReactアプリを実行し、仮想DOMの更新や、SPAとしての実行にうまいこと繋げてくれます

- 静的サイト生成(SSG)もできる
    - 事前に静的なHTMLやjsなどを作って、それをホストする形式
 
https://qiita.com/uehaj/items/1b7f0a86596353587466#gatsby%E3%81%AE%E5%8B%95%E4%BD%9C

> Reactアプリをビルド時に1回実行し、HTMLを生成します。HTMLを生成する動作はSSRと同様なのですが、サーバ上ではなく、ビルドマシン上で実行することが異なります。このHTMLをJSと共にデプロイし、ブラウザはそれを初期ページとして読み込み、SSRと同様にReactアプリの実行が再度なされ、仮想DOM更新、SPAとしての実行、Reduxステートなどが引き継がれます