Redux学び_3

今回も前回の続きからです。

https://qiita.com/ttttkkkkccccc/items/9c05371039604afd0119


ルーティングの設定（middlewareの導入）

ルーティング用ライブラリー
１、react-router(Reactのルーティング用ライブラリー)
２、connected-react-router（ReduxのStoreでルーティング管理）

**middlewareの導入**
store.js

```jsx
import {
  createStore as reduxCreateStore,
  combineReducers,
  applyMiddleware
} from "redux";
import{ connectRouter, routerMiddleware} from "connected-react-router";

export default function createStore(history) {
  return reduxCreateStore(
    combineReducers({
      router: connectRouter(history),
      users: UsersReducer
    }),
    applyMiddleware(
      routerMiddleware(history)
    )
  )
}

//historyは今いるURLの場所、パスの状態ということ？
//以下はReduxのStoreにstateを生成してhistoryのパスはどこなのかを指している。
combineReducers({
      router: connectRouter(history),
      users: UsersReducer
    }),

// 以下はrouterをMiddlewareとして使いますよ〜と宣言している。
applyMiddleware(
   routerMiddleware(history)
)
```

**StoreとRouterの接続**
⇨以下までできたら、storeにルーティングの情報を持たせることができる。

index.js

```jsx
import {ConnectedRouter} from 'connected-react-router';
import * as History from 'history';

const history = History.createBrowserHistory();
export const store = createStore(history);

<ConnectedRouter history={history}>
   <App />
</ConnectedRouter>

//createBrowserHistory()は現在のブラウザのULR（パス）を取得する。
//Appコンポーネントをラッピングしてパスが変わった時点でstateも変更できる
```

**Routerコンポーネントを作る**
⇨ブラウザのURLによってコンポーネントが切り替わる。

src/Router.jsx

```jsx
import React from 'react';
import {Switch, Route} from 'react-router';
import {Login, Home} from './templates';

const Router = () => {
  return(
    <Switch>
      <Route exact path={ "/login" } component={Login} />
      <Route exact path={ "(/)?" } component={Home} />
    </Switch>
  )
}
```

Switchとexactはセットの考え方でいいが、
⇨もしexactがない場合、pathが部分一致で遷移するということだけ頭に入れたほうがいい。
⇨セットとして使う場合はURLと完全一致した時に遷移するということ。

使わない場合は例である。
ブログ記事のような投稿にそれぞれにidが付いている時など。

```jsx
<Route path="/posts/:id" component={Post} />
```

templatesファイル作成

```jsx
import React from 'react';
import {useDispatch} from 'react-redux';
import {push} from "connected-react-router";

const Login = () => {
  const dispatch = useDispatch();
  return (
    <div>
      <h2>ログイン</h2>
      <button onClick={() => dispatch(push('/'))} >ログイン</button>
    </div>
  );
}

export default Login
```

### re-ducksパターンでファイル管理

メリット
１、actionsとreducersがシンプルになる
２、ファイルが肥大化しにくくなる。
３、ファイルごとの役割が明確になり管理しやすい。

各ファイルの役割

**operations**

１、複雑な処理を任せられる
２、redux-thunkで非同期処理の制御を行う
３、Actionsを呼び出す。

例

onClickイベントでoperationsに定義している関数呼び出し、何か処理を行い、このoperationsファイルからActionsを呼び出す。Actionsは単純にreducersにどんなデータを渡すか、そしてreducersはStoreのstateを変更してくださいね〜という流れ。

**types**
１、TypeScriptで使う
２、型定義を記述するしてexport

**selectors**
１、Storeで管理しているstateを参照する関数
２、reselectというnpmモジュールを使う。

users/selectors.js

```jsx
import {createSelector} from 'reselect';

const useSelector = (state)  => state.users;

export const getUserId = createSelector(
  [useSelector],
  state => state.uid
)

//Storeのstateのusersのuidをこの関数で呼び出している。
```

例（今回はHome.jsxに上記のgetUserIdを呼び出し、uidの表示）

```jsx
import React from 'react';
import {getUserId} from '../reducks/users/selectors';
import {useSelector} from 'react-redux';

const Home = () => {
  const selector = useSelector(state => state);
  const uid = getUserId(selector);

  return(
    <div>
      <h2>HOME</h2>
      <p>{uid}</p>
    </div>
  )
}

export default Home;

//selectorにStoreのstateを入れる。
//getUserIdの引数にselectorを入れて使う形。
```

**redux-thunk**
⇨Reduxで非同期処理を制御するライブラリー

store.js

```jsx
import thunk from 'redux-thunk';

例
applyMiddleware(
   routerMiddleware(history),
   thunk
)
```


Reduxは学習は基本的に終了です。
ありがとうございました。