SAMURAI TERAKOYA

【React hooks】useState・propsの基礎を習得 – カウンターアプリ

React.js

本記事内では、React hooksで提供される関数の一つである「useState」とpropsの基礎的な使い方をカウンターアプリを作成しながら解説していきます。

加えて、公式ページの内容にも少し触れていきたいと思いますので、参考になればと思います。

【本記事で作成していくカウンターアプリ (動作も確認可能です。)】

useStateについて

React hooksにおいて提供されている関数の1つになり、値の状態の保持・更新などを行う際に使用されている関数になります。

定義方法は、以下のようになります。

const [現在の状態を保持する値, 更新するための関数] = useState(初期値を設定)

第一引数に現在の値の状態を保持する変数を設定し、第二引数には、値を更新するための関数を設定します。useStateの()内に設定する初期値が第一引数の最初の値として設定されます。

propsについて

Reactでは、親のコンポーネントから子のコンポーネントへ値を受け渡すことが可能です。この流れを「propsを渡す」と言ったりします。 あくまで親から子への一方通行になりますので、子から親へは値を渡すことは出来ません。

props_流れ_図

※ 書き方については、カウンターアプリを作成する際にご説明します。

カウンターアプリを作成

※ 新規アプリの作成に関する手順は省きます。

ファイル・フォルダ階層

結果を表示させるためのコンポーネントとしてCounterResult.jsをsrcフォルダ内に作成してください。また、srcフォルダ内にchildフォルダを作成し、その中にはCSSを記述するCounter.cssを作成しましょう。

src
 - App.js
 - Counter.css
 child
   - CounterResult.js

親コンポーネント : App.jsの記述①

まずは、App.js内のベースとなるコードを書いていきます。

App.js①
  • 必要なファイルやuseState関数をimportする

    import { useState } from "react";
    import CounterResult from "./child/CounterResult"
    import "./Counter.css"

  • App関数を作成

    // App関数を定義
    const App = () => {
      return (
      // <React.Fragment></React.Fragment>を省略して、<></>と記述が可能
      // <></>内に複数の要素を記述
       <>
       </>
      );
    };
    
    // exportすることで、他のコンポーネントでimportできるようになる
    export default App;

     

  • useStateを定義する

    // 初期値として設定する変数を定義
    let initialState = 0;
    
    // useStateを記述
    // 第一引数をcountval, 第二引数をsetCountVal にする
    // useState(initialState) -> countvalの初期値を0に設定
    const [countval, setCountVal] = useState(initialState);
    

  • returnで返すHTML等を記述

    return (
      <>
      <div className="main">
       <h1>Counter_App</h1>
      </div>  
      </>
    );

  • 現時点でのApp.js内のコード&実行結果

    import { useState } from "react";
    import CounterResult from "./child/CounterResult"
    import "./Counter.css"
    let initialState = 0;
    const [countval, setCountVal] = useState(initialState);
    const App = () => {
      return (
       <>
         <div className="main">
         <h1>Counter_App</h1>
        </div>  
       </>
      );
    };
    
    export default App;

    現在の状態で実行してみると、次のように表示されます。

    react_state_props_App.js①

子コンポーネント : CounterResult.jsの記述①

CounterResult.js内には、カウンターアプリで数値を+1するブタンと-1するためのボタン,リセットボタンに加え、現在の数値を表示するための場所を作っていきます。

CounterResult.js①
  • CounterResult関数を作成

    // CounterResult関数を定義
    const CounterResult = ({}) => {
      return (
       <>
       </>
      );
    };
    
    export default CounterResult;

  • 現在の数値を表示するためのh2要素を記述

    <>
      {/* {}内で現在の数値を取得する */}
      <h2>{}</h2>
    </>

  • 数値を+1するブタンと-1するためのボタン,リセットボタンを記述

    <>
      {/* {}内で現在の数値を取得する */}
      <h2>{}</h2>
      <div className="button_group">
        {/* +ボタン, -ボタン, resetボタンを記述 */}
        {/* onClick={}内には後ほど、App.jsから渡される関数を記述します。 */}
        <button onClick={}>+</button>
        <button onClick={}>-</button>
        <button onClick={}>reset</button>
      </div>
    </>

  • 現時点でのCounterResult.js内のコード

    const CounterResult = ({}) => {
      return (
        <>
          <h2>{}</h2>
          <div className="button_group">
            <button onClick={}>+</button>
            <button onClick={}>-</button>
            <button onClick={}>reset</button>
          </div>
        </>
      );
    };
    
    export default CounterResult;

親コンポーネント : App.jsの記述②

こここでは、CounterResult.js上にある各ボタンがクリックされた際に呼ばれる関数を記述していきます。また、正常に関数を呼び出すためには子コンポーネントにpropsを渡す必要があるのでそこも併せてコードを追加します。

App.js②
  • 呼び出された時に数値を+1する関数を定義

    ①〜③までは、useStateの記述の後に順番に記述していきましょう。

    const CounterUp = () => {  
      // 更新処理 ⇨ setCountVal関数を記述
      setCountVal(prevcount => prevcount + 1);
    }
    useState_処理の流れ

     

    setState関数が引数(今回で言うと「prevcount」の箇所)として受け取る値について、公式ページ上では次のように記載されております。

    新しい state が前の state に基づいて計算される場合は、setState に関数を渡すことができます。

    フック API リファレンス – React
    ユーザインターフェース構築のための JavaScript ライブラリ

  • 呼び出された時に数値を-1する関数を定義

    更新前の数値が0もしくは0未満の場合は更新せず、0より大きい数値の場合にのみにprevcount – 1を実施するようなコードを三項演算子で書いています。

    const CounterDown = () => { 
      setCountVal(prevcount => 
        // prevcountが0より大きい場合にのみ更新前の数値を-1する
        prevcount > 0 ? prevcount - 1 : prevcount);
    }

  • リセットボタンを押された場合は、数値を初期値(0)に戻してあげます。

    const CounterReset = () => {  
      // 更新する値として、0を設定
      setCountVal(initialState);
    }

  • CounterResultコンポーネントの配置&propsの設定

    propsとしてコンポーネントに渡す値は、渡したいコンポーネントに対して指定します。今回は、現在の数値と加算用の関数・減算用の関数・リセット用の関数を渡していきます。

     

    countval, Up, Down, Resetは渡したい値を格納するものですが、任意の名前で構いません。また、propsはオブジェクトとして渡すため、渡す値は、{}で囲んであげる必要があります。
    <CounterResult 
      // propsとして渡す値の数については、限りはない
      countval={countval} 
      Up={CounterUp} 
      Down={CounterDown}
      Reset={CounterReset} 
    />
    

  • 最終コード

    import { useState } from "react";
    import CounterResult from "./child/CounterResult"
    import "./Counter.css"
    let initialState = 0;
    const [countval, setCountVal] = useState(initialState);
    const App = () => {
    
     const CounterUp = () => {  
        setCountVal(prevcount => prevcount + 1);
      }
    
      const CounterDown = () => { 
        setCountVal(prevcount => 
          prevcount > 0 ? prevcount - 1 : prevcount);
      }
    
      const CounterReset = () => { 
        setCountVal(initialState);
      }
    
      
      
      return (
       <>
         <div className="main">
         <h1>Counter_App</h1>
           <CounterResult 
               countval={countval} 
               Up={CounterUp} 
               Down={CounterDown}
               Reset={CounterReset} 
           />
        </div>  
       </>
      );
    };
    
    export default App;
    

子コンポーネント : CounterResult.jsの記述②

最後に、Counter Result.js上でpropsを受け取り、仕上げをします。

CounterResult.js
  • porpの取得

    CounterResult関数の引数として、propsを取得します。
    const CounterResult = ({countval, Up, Down, Reset}) => { 

  • 取得したpropsを使用

    h2要素には、現在の数値を保持している{countval}, button要素内のonClickには、{Up},{Down},{Reset}を設定します。

    <h2>{countval}</h2>
    <div className="button_group">
      <button onClick={Up}>+</button>
      <button onClick={Down}>-</button>
      <button onClick={Reset}>reset</button>
    </div>

    これで各種ボタンをクリックした際に、関数が呼び出され、処理が実行されるようになります。

  • 最終コード

    const CounterResult = ({countval, Up, Down, Reset}) => {
      return (
        <>
          <h2>{countval}</h2>
          <div className="button_group">
            <button onClick={Up}>+</button>
            <button onClick={Down}>-</button>
            <button onClick={Reset}>reset</button>
          </div>
        </>
      );
    };
    
    export default CounterResult;

    コードの記述自体は、ここまでで完了になります。問題なさそうであれば実行してみてください。次のように表示されていることに加え、各種ボタンが機能していればOKです。

    Counter_コード記述完了

Counter.css内にCSSを記述

最後にアプリ内(App.js, CounterResult.js)で使用するCSSを記述していきます。以下のコードをCounter.css内に記述してください。

#root {
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: azure;
}

.main {
  margin: 0 auto;
  border: 2px dashed darkblue;
  padding: 30px;
}

.main h2, .main h1 {
  text-align: center;
  margin-top: 0px;
}

.main h1 {
  color: rgb(88, 189, 230);
}

.button_group {
  display: flex;
  justify-content: space-around;
}

.button_group button {
  font-size: 20px;
}

動作確認

CSSの記述も問題なければ、以下のコマンドを実行し、動作の確認をしてみましょう。

cd プロジェクトフォルダ
npm start

埋め込んでおりますDEMOと同様に表示され、動作すれば、カウンターアプリの完成です。

まとめ

本記事では、カウンターアプリを通して、以下の内容を確認していきました。

  • 親コンポーネントから子コンポーネントへのpropsの渡し方
  • 子コンポーネントでのpropsの受け取り方
  • useStateの定義方法及び使用方法
  • setStateが保持する値

次回は、useReducerについてまとめていけたらと思います。

 

コメント

タイトルとURLをコピーしました