Redux Toolkit Tutorialを通してreduxを学ぶ　#1

## はじめに
本記事は、以下Youtubeで学んだ内容を基に、自分なりの理解をまとめたものです。
・Reduxを使用した場合
・Reduxを使用しなかった場合

の両方のコードを比較し、初学者目線でreduxを活用するメリットについて記述します。

#1では、サンプルプロジェクトの事前準備を行います。

<br>

<iframe width="560" height="315" src="https://www.youtube.com/embed/yZqBVLcWSn8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


<br>
間違い等あれば是非ご指摘ください。



## 目次
- 環境
- 事前準備
- ここまでの動作確認

## 環境
MacOS Ventura version 13.3.1
react version 18.2.0

## 事前準備
プロジェクトの作成
```
$ mkdir sample_ts_project
$ npx create-react-app . --template typescript
```

<br>
publicフォルダ配下の不要なファイルを削除（index.html以外を削除する）

```
$ cd public
$ ls . | grep -v -E 'index.html' | xargs rm -rf 
```

htmlと同じ階層にcssを用意する
```
$ touch styles.css
```

htmlとcssファイルを編集
（このあたりは学習内容と関係ないので特にこだわらなくていい）

``` html:public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>React-Redux-Test-App</title>
    <link font-family: "Montserrat", sans-serif;
    href="https://fonts.googleapis.com/css?family=McLaren|Montserrat&display=swap"
    rel="stylesheet" />
    <link rel="stylesheet" href="styles.css" />
  	<link id="external-css" rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Montserrat&amp;display=swap" media="all">
  </head>
  <body>
    <div id="root"></div>
    <script src="../src/index.tsx" type="test/tsx"></script>
  </body>
</html>
```


``` css:public/styles.css
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html {
  font-family: "Montserrat", sans-serif;
}

header {
  background-color: #f5ba13;
  margin: auto -16px;
  padding: 16px 32px;
}

header h1 {
  color: #fff;
  font-family: "mcLaren", cursive;
  font-weight: 100;
}

.home,
.login,
.contact {
  padding: 16px 30px;
}

footer {
  position: absolute;
  text-align: center;
  bottom: 0;
  width: 100%;
  height: 2.5rem;
}

```


<br>
srcフォルダ配下の不要なファイルを削除（index.tsx以外を削除する）

```
$ cd ../src
$ ls . | grep -v -E 'index.tsx' | xargs rm -rf 
```

必要なパッケージをインストール
```
$ npm install --sav-dev react-router-dom
```

index.tsxを編集

``` tsx:src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./components/App";

const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement,);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

srcフォルダ配下にcomponentsフォルダを作成し、ファイルを作成
```
$ mkdir components　&& cd $_
$ touch App.tsx Contact.tsx Footer.tsx Header.tsx Home.tsx Login.tsx
```

App.tsxは、Home, Login, Contactそれぞれのページへのリンクを表示させる。

```  tsx:components/App.tsx

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Home from "./Home";
import Login from "./Login";
import Contact from "./Contact";

function App() {
  return (
    <div className="App">
        <Router>
          <Link to="/">Home </Link>
          <Link to="/login">Login </Link>
          <Link to="/contact">Contact </Link>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/login" element={<Login />} />
            <Route path="/contact" element={<Contact />} />
          </Routes>
        </Router>
    </div>
  );
}

export default App;

```

各ページ共通で使うヘッダとフッタを用意

```  tsx:components/Footer.tsx
function Footer() {
  const year:number = new Date().getFullYear();
  return <footer>Copyright ⓒ {year}</footer>;
}

export default Footer;

```

```  tsx:components/Header.tsx
function Header() {
  return (
    <header>
      <h1>REDUX-TEST-APP</h1>
    </header>
  );
}

export default Header;
```  

それぞれのページのコンポーネント作成

```  tsx:components/Contact.tsx
import Header from "./Header";
import Footer from "./Footer";

function Contact() {
  const username:string = "";
  return (
    <div>
      <Header />
      <div className="contact">Contact {username}</div>
      <Footer />
    </div>
  );
}

export default Contact;
```

```  tsx:components/Home.tsx
import Header from "./Header";
import Footer from "./Footer";

function Home() {
    const username:string = "";
  return (
    <div>
      <Header/>
      <div className="home"> Home route {username}</div>
      <Footer/>
    </div>
  );
}

export default Home;
```  

```  tsx:components/Login.tsx
import { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";

function Loign() {
  const [inputUsername, setInputUsername] = useState<string>("");
  const username:string = ""; 

  function handleLogin(event:any) {
    event.preventDefault();
    console.log("inputUsename: " +inputUsername);
  }

  function handleLogout(event:any){
    event.preventDefault();
    setInputUsername("");
  }

  return (
    <div>
      <Header />
      <div className="login">
        {username}
        <form className="login">
          <input
            name="loginV"
            placeholder="loginPH"
            value={inputUsername}
            onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                console.log(e.target.value);
                setInputUsername(e.target.value);
            }}
          />
          <button onClick={handleLogin}> Submit login</button>
          <button onClick={handleLogout}> Logout</button>
        </form>
      </div>
      <Footer />
    </div>
  );
}

export default Loign;
```

これで事前準備は完了




## ここまでの動作確認
以下コマンドでアプリが立ち上げられることを確認する。

```
$ npm start
```
現時点では、Loginページにて、
- ユーザ名を入力し「Submit login」ボタンを押下すると、Devtoolのコンソールに入力したユーザ名が表示される。
- 「Logout」ボタンを押下すると、テキストボックスの値がクリアされる。

続きは「#2」で記載。

## 関連記事
- [Redux Toolkit Tutorialを通してreduxを学ぶ　#2](https://qiita.com/atok/items/439aa976ad675ca1a097)

- [Redux Toolkit Tutorialを通してreduxを学ぶ　#3](https://qiita.com/atok/items/1f16deb76858023f5e5b)