見出し画像

Reactを極める!

3連休初日の昨日は夫婦ともども不調でした😅
眼精疲労と頭痛に苛まれておりました。
おそらく寒暖差と普段の姿勢の悪さや運動不足などが原因でしょうw
昨日は1日リフレッシュデイとして
ある程度復活したので、また今日から計画的に学習進めていきます。

恥ずかしながら、JavaScriptの知識も乏しかったので、
React以前の問題で時間を要していました。

こないだからやっとReactの根幹にはいったので、
今学習しているものをスケジューリングして
この後はサクサク進められるようにしていきます!


<イベントハンドラーについて>
onClick属性に渡すのは、「関数」自体ではなく「関数名」

そうしないとクリックしなくても関数自体が実行されてしまい
求める挙動とは異なってしまいます。

→最近少しずつ関数、変数、配列の書き方の違いが腑に落ちるようになってきたけど
ここはこういうものだと理解するしかないですね😅

<アロー関数本当にわかってる?>

基礎がない状態で「アロー関数」なんぞ使って、実務であわあわしてたので
再度復習。

実際にコードに書いて、ブラウザで検証しました。

function yahoo (){return 'yahoo!'} 
  
② const yahoo = function (){
     return 'yahoo!'
   }
  
③ const yahoo = () => {
    return 'yahoo!'
  }


return (
  <>
    <h3>{yahoo()}</h3>
  </>
  
)

①から③いずれもreturnで返ってくるものは同じです。

見やすく簡略化するなら③、私みたいな初心者はまずは①から順番に書いてってもいいかもですね。

<いろんなイベント>

<input
    type="text"
    onChange={() => console.log("onChange検知")}
    onBlur={() => console.log("onBlur検知")}
    onFocus={() => console.log("onFocus検知")}
/>

imput要素と一緒によく使う3つのイベント
onChange-フォーム内の値が変化したとき
onFocus-フォームにフォーカスしたとき
onBlur-フォームからカーソルが離れたとき

<コールバック関数について>

今更感ありますが

<input type="text" onChange={(e) => console.log(e.target.value)} />

他のイベントでは引数はいってこないのに、なんでこの場合ははいってくるか?

→理由(自分なりの解釈です)
・上でかいているものは、イベント自体がおこってるかどうかを見るためのもの
・今回のはイベントで取得した値を表示するもの。
だからイベントの中身から、プロパティ名をつなげて書くことで、内容を取得するため

<useStateについて>

入力値をリアルタイムで画面で再生できるようになる。

ではなぜuseStateが必要なのか。
以下2つの目的がある。
1️⃣:コンポーネントの再実行(再レンダリング)を依頼し、新しいReact要素を作成するため
2️⃣:変更した値をいったんどこかに保持するため(Stateに保存


配列の0番目に参照用の値、1番目に更新用の関数が入ってくる。

それに則って素直に書いたのがこちら。

const Example = () => {
  let valArray = useState();
  return (
    <>
      <input 
        type="text"
        onChange={(e) => {
          const setFn = valArray[1];    //配列の1番目(セッター)
          setFn(e.target.value)
      }} /> = {valArray[0]}    //配列の0番目(ゲッター)
    </>
  );
};

 これを分割代入で書いたものが、よくある形のやつ。

const Example = () => {
  const [val, setVal] = useState();
  return (
    <>
      <input 
        type="text"
        onChange={(e) => {
          // const setFn = valArray[1];
          setVal(e.target.value)
      }} /> = {val}
    </>
  );
};


ここでまた、「分割代入」の考え方が必要になってくる。
前もやった気がするけど、曖昧なので再度。

そもそも「分割代入」とは、JavaScriptで変数から値を取り出す方法の1つ。
特定のデータ(オブジェクトや配列)から要素を抽出して、新しい変数に代入するために使用される。

通常のJavaScriptの分割代入は

オブジェクト

const name = { firstName: 'Yamada', lastName: 'Taro' };

分割代入で値を取り出す書き方
const { firstName, lastName } = name;


配列

const nums = [1, 2, 3, 4, 5];

分割代入で値を取り出す書き方
const[first, second, ...rest] = nums;

useStateの場合

const [val, setVal] = useState();

valは現在の状態(更新した後も含めて)
setValは状態を更新するための関数
が割り当てられる。
この書き方は視覚的に直感でわかりやすくするための書き方でもある

useStateの役割と使い方をまとめると、

1️⃣Hook intoでReact内部に接続され、「こいつはState管理が必要なやつでっせ」という情報が送られる
2️⃣React内部の人が「そうかそうか、じゃあ今の値と更新する関数を配列にして返そう」と動いてくれる
3️⃣更新関数に値を渡すと
そのstateを含むコンポーネントが再レンダリングされる

注意として、コンポーネントごとにstateが保持されることを覚えておきたい。

import { useState } from "react";

const Example = () => {
  let displayVal;
  let [ val, setVal ] = useState();
  console.log('再レンダリングされました');
  return (
    <>
      <input
        type="text"
        onChange={(e) => {
          console.log(e.target.value);
          setVal(e.target.value);
          displayVal = e.target.value;
        }}
      />
      = {val}
    </>
  );
};

export default Example;

<自分で書いて確認してみよう>

サンプルの画面があったので、それと同じになるように解説を見ずに書いて見た!

import { useState } from "react";

const Example = () => {
  const [count, setCount] = useState(0);
  
  return(
    <>
      <p>現在のカウント数: {count}</p>

      <button onClick={()=>{setCount(count + 2)}}>+</button>
      <button onClick={()=>{setCount(count - 1)}}>-</button>
    
    </>
  );
};

export default Example;

結果、これでも間違いではないけど、可読性をよくするには、
onClickの後を最初に定義しておくといいみたい。

const countUp = () => {
   setCount(count + 2)
};

こう定義しておけば、buttonタグの中は{countUp}だけでOK。


ジムに行ったりして
1日の最後にstateの練習問題!

const Example = () => {
  return (
    <>
      <h3>練習問題</h3>
      <p>
        記述を変更し、完成コードのように+と-ボタンをクリックすると現在のカウント数が1ずつ増減する機能を実装してください。*useStateを用いてcountとsetCountを定義してください。
      </p>
      <p>現在のカウント数: {/* ここにcountを表示してください。*/}</p>
      <button>+</button>
      <button>-</button>
    </>
  );
};

export default Example;

あら?さっきのと同じかな?
まぁ復習になるからok!
私の答えはこちら。

import { useState } from 'react';

const Example = () => {

  const [count, setCount] = useState(0);
  const countUp = () => setCount(count + 1);
  const countDown = () => setCount(count - 1);
  return (
    <>
      <h3>練習問題</h3>
      <p>現在のカウント数: {count}</p>
      <button 
        onClick={countUp}>+</button>
      <button onClick={countDown}>-</button>
    </>
  );
};

export default Example;

模範回答はこちら。

import { useState } from 'react';

const Example = () => {
  const [count, setCount] = useState(0);
  
  const countUp = () => {
    setCount(state => state + 1);
  };

  const countDown = () => {
    setCount(state => state - 1);
  };
  return (
    <>
      <h3>練習問題</h3>
      <p>現在のカウント数: {count}</p>
      <button onClick={countUp}>+</button>
      <button onClick={countDown}>-</button>
    </>
  );
};

export default Example;

chatGPT先生によると、
模範のほうが、カウント値が競合する可能性が低いため安全だそう。

難しいけど、明日からも頑張ってこー!

駆け出しエンジニアなっちゃんの亀さんのような成長をあたたかく見守ってくださるとうれしいです。 自己研鑽に拍車をかけたいと思います!