見出し画像

0~3カ月目エンジニア向けReact+JS入門講座

はじめに


本記事をご覧いただきありがとうございます。今回は、0~3カ月目エンジニアに向けたReact+JavaScriptプログラミング記事をテーマに書いていきます。

まず、今回のプログラミング記事の難易度ですが、CLIの存在を知っている、プログラミングを軽く行ったことがある方向けの記事になります。

今回のテーマ


〇 React+JavaScriptでカウンタープログラムを作ってみよう!

それでは、まずは下記のプログラム「完成形」を見ていきましょう。

App.jsx

import { useState } from 'react'
import UiButton from './ui/UiButton'
import './App.css'

function App() {
  const textItems = ["+", "-", "×", "÷"]
  const [count, setCount] = useState(0)

  const operations = {
        "+": prev => prev + 1,
        "-": prev => prev - 1,
        "×": prev => prev * 2,
        "÷": prev => prev / 2,
  }

  function handleClick(e){
    setCount(operations[e])
  }
  

  return (
    <div className="container" >
      <p>{count}</p>
      <div className="grid">
        {textItems.map(e => (<UiButton key={e} text={e} click={() => handleClick(e)}/>))}
      </div>
    </div>
  )
}

export default App

UiButton.jsx

function UiButton({text, click}) {

    return (
        <>
        <button onClick={click}>
            {text}
        </button>
        </>
    )
}

export default UiButton

App.css

body {
    margin: 0;
    font-family: sans-serif;
}

.container {
    height: 100vh;

    display: flex;
    flex-direction: column;

    justify-content: center;
    align-items: center;
}

.grid {
    display: grid;

    grid-template-columns: 120px 120px;

    gap: 16px;
}

.calc-btn {
    width: 120px;
    height: 80px;

    font-size: 32px;

    border: none;
    border-radius: 12px;

    cursor: pointer;

    background: #d2aa19;
    color: rgb(255, 255, 255);
}

起動すると、このような形になります。

カウンタープログラム実行例

Reactとは


ReactとはJavaScript、TypeScriptの"ライブラリ"と呼ばれるもので、Webアプリケーションを作成していくうえで、便利な機能を提供してくれます。

通常、Webページを作成する際は、HTMLやCSSを1から構成する必要がありますが、ReactではMUIのようなUIデザイン用ライブラリも利用することができ、ボタンやプログレスバーなど、デザイン済みの部品を簡単に利用できます。

環境を準備していきましょう!


まずはPowerShellを開き下記のコマンドを実行してください。

sl ~
New-Item -ItemType Directory localDesktop\programs
sl localDesktop\programs

これで、プログラムをおこなう環境が作成されました。
localDesktopとは?など、色々思うところがあるかもしれませんが、普段私が使用している構成なため、もし詳しく知りたい場合に関しては、下記の記事を参考にしてください。

次にnpmコマンドを使えるようにしなければなりません。
npmコマンドに関しては、Node.jsをインストールすることで、自動で使用することができるようになります。

では、インストールしていきましょう。

winget install -e --id OpenJS.NodeJS
Node.js

このコマンド「winget install -e --id OpenJS.NodeJS」に関しては、毎回使うものではないですし、年代により変わる可能性があるので、覚えなくても問題ございません。

では、次に正しくインストールされたかを確認しましょう。

PS C:\Users\2toto> node -v
v26.1.0

上記のコマンドを入力して、バージョンが表示されていればインストールが成功しています。

次に、下記のコマンドを入力してください。

sl ~\localDesktop\programs
npm create vite@latest
v26.1.0
PS C:\Users\2toto> sl .\localDesktop\programs\
PS C:\Users\2toto\localDesktop\programs> npm create vite@latest
Need to install the following packages:
create-vite@9.0.7
Ok to proceed? (y) y # yと入力してEnterを押します。


> npx
> create-vite

│
◆  Project name:
│  counter-button█ # 好きな名前でOK 本記事ではcounter-buttonにしました。
実際の例

いくつか選択するものが表示されるので、Reactを選択します。

Reactを選択してください。

続いて、JavaScriptを選択します。

JavaScriptを選択してください。

上記を選択すると、プロジェクトが作成されます。

プロジェクトの作成

下記のような画面が表示されるので、「http://localhost:5173/」をブラウザで入力してみましょう。

npm run devコマンド実行

入力をすると、下記の様な画面が表示されます。

これからカウンタープログラムを下記の画面に作成していきます。

初回の画面例

カウンタープログラムの作成


それでは、実際にカウンタープログラムを作成していきましょう!

まずは、作成したプロジェクトに移動していきます。

sl ~\localDesktop\programs\counter-button; code .

VScodeで開いた、プロジェクト内は下記のような構成になっていますね。

デフォルトのプロジェクト内

今回はsrcにプログラムを追加していきます。それではsrcを開いていきます。

src内

src内には下記の4ファイルがあります。

  • App.jsx

  • App.css

  • index.css

  • main.jsx

ファイルについて説明していきます。

追加と削除

今回不要となるファイルやプログラムを削除していきます。

まずは、App.jsxの中を確認してください。

先ほどローカルで確認した画面のプログラムが記載されています。
このsrcがmain.jsxに渡されることで、画面に先ほどの映像が表示されていたわけですね。

表示されていた画面

今回、これらのデザインは不要なので削除していきます。

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      <section id="center">
        <div className="hero">
          <img src={heroImg} className="base" width="170" height="179" alt="" />
          <img src={reactLogo} className="framework" alt="React logo" />
          <img src={viteLogo} className="vite" alt="Vite logo" />
        </div>
        <div>
          <h1>Get started</h1>
          <p>
            Edit <code>src/App.jsx</code> and save to test <code>HMR</code>
          </p>
        </div>
        <button
          type="button"
          className="counter"
          onClick={() => setCount((count) => count + 1)}
        >
          Count is {count}
        </button>
      </section>

      <div className="ticks"></div>

      <section id="next-steps">
        <div id="docs">
          <svg className="icon" role="presentation" aria-hidden="true">
            <use href="/icons.svg#documentation-icon"></use>
          </svg>
          <h2>Documentation</h2>
          <p>Your questions, answered</p>
          <ul>
            <li>
              <a href="https://vite.dev/" target="_blank">
                <img className="logo" src={viteLogo} alt="" />
                Explore Vite
              </a>
            </li>
            <li>
              <a href="https://react.dev/" target="_blank">
                <img className="button-icon" src={reactLogo} alt="" />
                Learn more
              </a>
            </li>
          </ul>
        </div>
        <div id="social">
          <svg className="icon" role="presentation" aria-hidden="true">
            <use href="/icons.svg#social-icon"></use>
          </svg>
          <h2>Connect with us</h2>
          <p>Join the Vite community</p>
          <ul>
            <li>
              <a href="https://github.com/vitejs/vite" target="_blank">
                <svg
                  className="button-icon"
                  role="presentation"
                  aria-hidden="true"
                >
                  <use href="/icons.svg#github-icon"></use>
                </svg>
                GitHub
              </a>
            </li>
            <li>
              <a href="https://chat.vite.dev/" target="_blank">
                <svg
                  className="button-icon"
                  role="presentation"
                  aria-hidden="true"
                >
                  <use href="/icons.svg#discord-icon"></use>
                </svg>
                Discord
              </a>
            </li>
            <li>
              <a href="https://x.com/vite_js" target="_blank">
                <svg
                  className="button-icon"
                  role="presentation"
                  aria-hidden="true"
                >
                  <use href="/icons.svg#x-icon"></use>
                </svg>
                X.com
              </a>
            </li>
            <li>
              <a href="https://bsky.app/profile/vite.dev" target="_blank">
                <svg
                  className="button-icon"
                  role="presentation"
                  aria-hidden="true"
                >
                  <use href="/icons.svg#bluesky-icon"></use>
                </svg>
                Bluesky
              </a>
            </li>
          </ul>
        </div>
      </section>

      <div className="ticks"></div>
      <section id="spacer"></section>
    </>
  )
}

export default App

ポイント!
returnの中が表示されている。
下記のように修正します。

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
    </>
  )
}

export default App

これで、画面には何も表示されません。
importしてある下記3件のimport文も不要なので削除していきましょう。

  1. import reactLogo from './assets/react.svg'

  2. import viteLogo from './assets/vite.svg'

  3. import heroImg from './assets/hero.png'

import { useState } from 'react'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
    </>
  )
}

export default App

App.jsxは上記のような状態にしておいてください。useStateは使用しますので取っておきます。

次にindex.cssです。今回は使用しないため削除します。また本書ではCSSはある程度理解できる方向けの記事なため、CSSについての説明は省かせていただきます。

index.cssは削除する。

次に、App.cssを確認します。
こちらも中身をすべて削除して、下記のコードに修正してください。

body {
    margin: 0;
    font-family: sans-serif;
}

.container {
    height: 100vh;

    display: flex;
    flex-direction: column;

    justify-content: center;
    align-items: center;
}

.grid {
    display: grid;

    grid-template-columns: 120px 120px;

    gap: 16px;
}

.calc-btn {
    width: 120px;
    height: 80px;

    font-size: 32px;

    border: none;
    border-radius: 12px;

    cursor: pointer;

    background: #1976d2;
    color: white;
}

「.container」 は中央寄せ「.grid」はボタンを2列に並べるために使用しています。

次にmain.jsxです。このファイルでApp.jsxの内容を読み込んで画面に表示をさせています。

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

こちらも同様に、不要な行「import文」を削除していきます。
下記のように修正を行ってください。

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

これで、不要なプログラムやファイルを削除できたので、現状を確認していきましょう。

現在のsrc内

プロジェクト内が画像の通りとなっていれば問題ございません。

では次にPowerShellで下記のコマンドを実行しましょう。

# VSCodeでファイルを簡単に作成できますが、コマンドを練習しましょう。
sl ~\localDesktop\programs\counter-button\src
New-Item -ItemType Directory ui
sl ui
New-Item UiButton.jsx

上記を実行すると、下記のようにファイルが生成されます。

ファイルとフォルダを作成

UiButton.jsxの作成


では、カウンタープログラムのボタン部分を作成していきます。
下記のように入力してください。

function UiButton({text, click}) {

    return (
        <>
        <button onClick={click}>
            {text}
        </button>
        </>
    )
}

export default UiButton

function UiButton({text, click}) とすることで、propsからtextとclickを分割代入して受け取ることができます。

例えば親コンポーネント(App.jsx)で、

<UiButton text="hoge" click={func} />

のように指定すると、子コンポーネント側でtextとclickを使用できます。


この場合、ボタンには「hoge」と表示され、クリック時にfuncが実行されます。

なお、function UiButton(props) のように書いてもpropsは受け取れますが、{text, click} と書くことで props.text や props.click を毎回書かずに済むため、コードが見やすくなります。

最後に export default UiButton とすることで、他のファイルからインポートして使用できるようになります。

App.jsx


では、早速本体部分を作成していきましょう。
App.jsxに先ほど作成したUiButtonをインポートしてみましょう。

import { useState } from 'react'
import UiButton from './ui/UiButton' //この行を追加してUiButtonをインポート 
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
    </>
  )
}

export default App

そして、returnの中に配置してみましょう。

import { useState } from 'react'
import UiButton from './ui/UiButton'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <div className="container" >
      <UiButton />
    </div>
  )
}

export default App

では、この状態で画面がどのようになっているかを確認します。
空のdivタグのままでは、ボタンが中央に表示されないため、先ほど用意したApp.cssのcontainerを使用しましょう。

また、このままだとボタンが小さいので下記のようにUiButtonを一旦修正してください。

<button onClick={click} style={{ height: "50px", width: "100px" }}>{text}</button>

では、実際にプロジェクト内で下記のコマンドを実行してローカルホストを立ち上げてください。

npm run dev

このように、ボタンが表示されました。

表示されたボタン

では次に、ボタンが押されたら数が増えていくようにします。
下記のようにsrcを修正してください。

import { useState } from 'react'
import UiButton from './ui/UiButton'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  function handleClick() {
    setCount(count + 1)
  }

  return (
    <div className="container" >
      <p>{count}</p>
      <UiButton text="hoge" click={handleClick}/>
    </div>
  )
}

export default App

まず、<UiButton text="hoge" click={handleClick}/>でボタンのテキストをhogeにし、clickに作成した関数であるhandleClickを渡しています。

そのため、ボタンをクリックした際に、handleClickが実行されます。handleClickの中では、setCount(count + 1)を実行しています。

setCountは、ReactフックであるuseStateの状態を更新するための関数です。count + 1を渡すことで、countの値を更新し、Reactが再レンダリングを行います。

そのため、画面上のcountの表示部分が更新されてボタンを押すたびに、数字が増えていきます。

カウンタを追加

次に、同じ要領で足し算、引き算、掛け算、割り算を追加していきます。

まずは、直観的にプログラムを記載してみましょう。

import { useState } from 'react'
import UiButton from './ui/UiButton'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  function plus() {
    setCount(count + 1)
  }

  function minus() {
    setCount(count - 1)
  }

  function multiplication() {
    setCount(count * 2)
  }

  function division() {
    setCount(count / 2)
  }

  return (
    <div className="container" >
      <p>{count}</p>
      <div className="grid">
        <UiButton text="hoge" click={plus}/>
        <UiButton text="hoge" click={minus}/>
        <UiButton text="hoge" click={multiplication}/>
        <UiButton text="hoge" click={division}/>
      </div>
    </div>
  )
}

export default App

このように四つのボタンが配置され、正しく計算がされますね。

ボタンを4つ追加

ただし、このような記述ではボタンごとに設定を行わなくてはならず非効率です。そのため下記のように修正します。

import { useState } from 'react'
import UiButton from './ui/UiButton'
import './App.css'

function App() {
  const textItems = ["+", "-", "×", "÷"]
  const [count, setCount] = useState(0)

  const operations = {
        "+": prev => prev + 1,
        "-": prev => prev - 1,
        "×": prev => prev * 2,
        "÷": prev => prev / 2,
  }

  function handleClick(e){
    setCount(operations[e])
  }
  

  return (
    <div className="container" >
      <p>{count}</p>
      <div className="grid">
        {textItems.map(e => (<UiButton key={e} text={e} click={() => handleClick(e)}/>))}
      </div>
    </div>
  )
}

export default App

このようにすることで、return内に1つずつ記述することなくボタンを生成することが可能です。

それでは、追加したコードについて確認していきましょう。

const textItems = ["+", "-", "×", "÷"]

上記はtextItemsという名前の配列を定義しています。

{textItems.map(e => (<UiButton key={e} text={e} click={() => handleClick(e)}/>))}

map関数は、配列の値を順番に取り出して、それぞれ指定した「e」に代入することで、配列の要素数分のボタンを生成しています。

const operations = {
        "+": prev => prev + 1,
        "-": prev => prev - 1,
        "×": prev => prev * 2,
        "÷": prev => prev / 2,
  }

operationsというオブジェクトを作成しています。
+というkeyにはvalueとしてprev => prev + 1を指定しているため、operations["+"]と呼んだ場合は「prev => prev + 1」という関数を取得します。

function handleClick(e) {
        setCount(operations[e])
    }

ボタンがクリックされた際に、そのボタンの値を関数handleClickに渡しています。

operations[e]は、対応する計算用の関数を取得しています。
例えば「e」が「+」である場合「+」のvalue「prev => prev + 1」という関数が取得されます。

このoperations[e]で取得した関数を、setCount()に渡すことで、Reactが現在のcountの値をprevに渡して、新しい値を計算しstateを更新します。

その結果、画面が再レンダリングされ、countの表示が更新されます。

ポイント!
setCountには値だけではなく、現在のstateを受け取る関数を渡すこともできます。

click={() => handleClick(e)}

そのまま、click={handleClick(e)}とした場合、生成されたと同時に実行されてしまうため、アロー関数「() =>」で囲むことで、ボタンが呼ばれるまでhandleClick(e)の実行を待機しています。

では解説が完了したところで、最後にボタンにCSSも追加しましょう。

UiButton.jsxを下記のように編集してローカルを確認してください。

注意:ReactではHTMLのclassではなく、classNameを使用してCSSクラスを指定します。

import '../App.css'
function UiButton({text, click}){
    return(
    <>
        <button className="calc-btn" onClick={click}>{text}</button>
    </>
    )
}

export default UiButton

下記のようにボタンのデザインが変われば成功です。

完成形

最後に。


如何でしたか?上手に作成することはできましたか?
今回の記事は0~3カ月目のエンジニアに向けて記載させて頂きました。

JavaScriptは、始めは覚えることが多く大変だと思いますが、一つひとつ理解を深めていくことで、コードの記述が楽になってきます。

私は、JavaScript系で初めて学習を行ったのがTypeScriptでしたが、その時は記号の意味などをあまり理解せず進めていたため、理解するのに時間がかかってしまいました。

そのため、記号の意味やプロップスの意味などはうやむやにせずしっかりと理解して進めることが、一番の近道です。

それでは、ここまでご覧いただきありがとうございました。

その他にも、SESエンジニアに向けての記事を記載しています。
もしよろしければご覧ください。



いいなと思ったら応援しよう!