JavaScript(React)の勉強中のメモとか
フロント勉強してみたいからJavaScriptとReactを勉強してみよう
勉強中に詰まったとことかエラーになったとこをメモ代わりに投げていくScrap
勉強の教材はUdemyのこれ。
【最新ver対応済】モダンJavaScriptの基礎から始める挫折しないためのReact入門
Reactに入門した人のためのもっとReactが楽しくなるステップアップコース完全版
GitHub
開発用リポジトリ: https://github.com/arusuDev/Udemy_React
どれくらい経験あるの?
HTMLとCSSの基礎の基礎くらいは知ってる
JavaScriptについてはど素人
ReactについてはJSのフレームワークで最近はやってるっぽい!
でも何できるのかわからん!! ってレベル
なんで勉強するの?
現職をやめて来年から違う会社に務めるので技術者としてフロントとかAWSを知っておきたいなーという気持ちから。
現状の進捗は?
1つ目のReact入門の動画半分くらい進んでます
素のJavaScriptでToDoアプリ作り始めました。
開発環境は?
講座内だとCodeSandboxっていうサイトで開発をすすめているけど、手元でやりたかったので
VSCode + WSL2(Ubuntu) でVSCodeの拡張 LiveServerを使ってブラウザ(FireFox)上で動作確認をしながら進めてます。
Zenn Scrap使うの初めて!
オンラインで軽くメモできるサイトないかなーと思ったときに頭の片隅にあったZenn Scrapを使ってみようと。堅苦しくないアウトプットの場所として使えそうだったのが選択理由。
JavaScriptをHTMLのボタンから呼び出そうとしたときに、恥ずかしながらいきなり躓いたので色々出てくるだろうと備忘録代わりにこのスレッドを立てました。
1.buttonを押してもJSが反応しない
原因
以下のコードの記載位置が間違っていた。
<script src="index.js"></script>
<body>
タグの一番上に書いていたので、document.getElementById
で指定したidが出てくる前に処理してしまいnullになっていた。
(このレベルで何もわかってないです。)
2.JavaScriptでDOMを作っていく手順
// li生成
const li = document.createElement("li");
// div生成 (class list-row)
const div = document.createElement("div");
div.className = "list-row";
// p生成 (class todo-item)
const p = document.createElement("p");
p.className = "todo-item";
p.innerText = inputText;
// 階層構造の作成 li -> div -> p
div.appendChild(p);
li.appendChild(div);
// id=imcomplete-listの下に要素を追加
document.getElementById("imcompleate-list").appendChild(li);
- createElement関数でタグを作る
- appendChild関数で階層構造を作る
- documentの要素に対してappendChildする
3.DOM要素は参照で持っている
document.getElementByIdで取得した要素を、別の場所にappendChildしたときに
元の位置からは削除され、appendChildしたときの位置に移動する
JavaScriptでのToDoアプリの実装ができた
ここまでの感想
体系的に学んだことが一回もなかったので、DOMの操作の仕方とかのイメージが全然掴めてなかったんだけど、
実際にToDoアプリを作っていく中で、各DOM要素の参照仕方とかがわかって意外と思っていたよりとっつきにくくは
ないかな?っていう印象。
DOM要素参照で持ってるから、移動させたら元の位置から消えるとか、HTMLは上から処理されていくとか
きっと基礎中の基礎の部分だとは思うけど、なるほどとなっている
あとアロー関数とかそのあたりの記法についても最初に説明してくれてるから、JSって記法がよくわからん!!って
なってた部分もだいぶクリアになって簡単なコード読めるかも?ってなった。
小休憩を挟んで今日中に一本目は最後まで行こう!
余談
ChatGPT君にコミットメッセージの添削をしてもらってる。
Reactの開発環境について
ローカル(WSL)で開発環境を作っていたので、WSL側のUbuntuでReactのプロジェクトを作成するコマンドcreate-react-app
を利用できるように。
上記コマンドを使うには、nodejsをインストールする必要があるみたいなので、
aptパッケージからNodejsをインストール。
その結果バージョンはv12が入ったけれど、コマンドを利用するためにはnodejs v14以上にしてくださいとの文章が。
そこで最新nodejs v20を入れるため以下手順を実施。
sudo apt-get install npm
sudo npm install n -g
-
sudo n stable
念のためapt側で入れたnodejsをアンインストール sudo apt purge -y nodejs npm
sudo apt autoremove -y
上記手順でv20.10.0をインストール、create-react-app
を使うことができました!
apt側のリポジトリだと更新されてないみたいだね。
デフォルトのパッケージ管理ソフトで使う人も多そうだけどなんでなんだろ?
4.Reactの構文でJavaScriptを起動したけど動かない
動画を参考にReactでのHello Worldを書いてみた。
HTMLはcreate-react-app
の雛形をそのまま利用。
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<h1>Hello React</h1>
</StrictMode>
);
Live Serverを起動して、htmlファイルを表示、
でHello Reactとは表示されず真っ白い画面に。
実際問題HTMLにもjsファイルにもお互いを参照する(ファイルパス)記載はないわけで。
そりゃ真っ白い画面になるか、とも思い調べてみたところ、
Reactの記載をしたらReactのサーバーを起動してあげないとダメみたいですね。
サーバー起動時に依存関係の解決とかしてくれてるみたい。
今日は遅くなってしまったので、続きは明日夜やろうと思うけれども、
きっとReact用の拡張機能もありそうかな?
コンパイルに20秒くらい?(体感)かかるので、もう少し効率のいい方法があるといいな。
解決
これ、WSL2で/mnt/(drive名)/~以下に配置してると起きるみたい。
Windows側のディレクトリで作ったフォルダにシンボリックリンク切って使ってたから、
めちゃめちゃコンパイルに時間がかかってLiveServerの自動更新も効かなかったみたい。
/home/(username)/以下にフォルダ移動してきたら解決しました!
5.コンポーネント名はPascalCaseで書く(単語の頭は大文字)
//OK Case
export const App = () => {return (
<div>
<h1>Hello React</h1>
<p>Hello.</p>
</div>
);
};
//NG Case
export const app = () => {return (
<div>
<h1>Hello React</h1>
<p>Hello.</p>
</div>
);
};
6.Reactで要素を記載するときはCamelCaseで書く(先頭を除く単語の頭は大文字)
export const App = () => {
const onClickButton = () => alert();
// CSS インラインスタイル
// Reactで記載する場合はcamelCaseで書くこと。
// fontsize -> fontSize
// 数値は数値として記載できるが、オブジェクトとして使うため、
// colorコードなどは文字列として定義する。
const contentStyle = {
color: "blue",
fontSize: "3rem",
};
return (
<div>
<h1 style={contentStyle}>Hello React!</h1>
<button onClick={onClickButton}>ボタン</button>
</div>
);
};
7.再レンダリングの条件
- Stateが更新された時
- propsが更新された時
- 親のコンポーネントが再レンダリングされた時
8.Reactで引数ありの関数をbutton等に割り当てたい場合
引数ありの関数を割り当てる場合、{関数名(引数)}とすると挙動が想定通りにならない。
上手く行かない実装例
<p className="area-title">未完了のToDo</p>
<ul>
{imcompleteToDos.map((todo, index) => (
// 一意になる値を設定する
<li key={todo}>
<div className="list-row">
<p className="todo-item">{todo}</p>
<button>完了</button>
<button onClick={onClickDelete(index)}>削除</button>
</div>
</li>
))}
</ul>
{}内はJavaScriptとして解釈されてしまうため、mapで生成するたびに{}が実行され、関数を実行してしまう。
解決策
<p className="area-title">未完了のToDo</p>
<ul>
{imcompleteToDos.map((todo, index) => (
// 一意になる値を設定する
<li key={todo}>
<div className="list-row">
<p className="todo-item">{todo}</p>
<button>完了</button>
<button onClick={() => onClickDelete(index)}>削除</button>
</div>
</li>
))}
</ul>
関数化してあげれば即時実行されないので回避できる。
一区切り
入門用の教材は終了、思ったより時間かかけてしまったけど、引き続きステップアップ側もやっていこう。
JavaScriptと比較してReactはコンポーネントの再利用が凄くしやすそうだなぁという感触。
画面内の要素をコンポーネント化して行ってリファクタリングしていく作業が楽しかった。