まえがき
百聞は一見に如かずということで、TODOアプリを作りながらReactを学んでいきます。
環境構築&プロジェクト作成
基本的に↓に書いてある通り進めていく。
・NodeJSがインストールされていること node -v
・プロジェクト作成
# React × JavaScript
npx create-react-app react-practice
# React × TypeScript
npx create-react-app react-practice --template typescript
・動作確認
cd react-practice
npm start
プロジェクト構成
・src
- Reactのソースコードをここに書いていく。
・public
- HTMLファイル/画像ファイル等 ... HTTPリクエストで取得されるやつら
レンダリングの流れ
index.htmlとindex.js
・index.htmlに対して、React(JavaScript)がレンダリングの処理をかける。
・ReactDOM.render()
=レンダリング
・ReactDOM.render(①React要素, ②①を反映する場所)
①React要素 を ②index.htmlの<div id="root"></div>
に反映する。
App.js
・index.jsではimport App from './App';
で参照しているApp.js
を元にレンダリングしているので、このApp.jsとそれに繋げるコンポーネントを作成していくことでReactアプリケーションを実装していく流れとなる。
・exportされているApp関数は、HTMLっぽいやつを戻り値に返す関数。
・index.jsのReactDOM.render()
の第1引数にはReact要素を渡す必要があるので、このHTMLっぽいやつを書けばReact要素が生成される。
HTMLっぽいやつの正体 = 「JSX」というプログラミング言語
・HTMLっぽいやつは「JSX」というプログラミング言語である。
・JSXで書かれた処理はReact.createElement関数でReact要素を生成する処理に変換される。
↓なぜ?↓
・ReactDOM.render()の第1引数に渡すReact要素を生成する処理が、まさにこのReact.createElement関数だから。
・毎回↓のような書き方をしてReact要素を定義するよりも、JSXのようなHTMLっぽいやつの方が当然書きやすいからJSXを使うよね~という感じ。
// aは"React要素"
var a = React.createElement('h1', { myaddr: 'bar' }, 'First element!')
// 第1引数にReact要素が渡される
ReactDOM.render(a, document.getElementById('root'))
React.createElement関数の戻り値
・React.createElement returns an object that represents the DOM element.
const element = React.createElement("h1");
//returns an object similar to this one:
{
type: 'h1',
props: {}
}
TODOアプリ作っていく。
入力して追加する
参考
TODOアプリ作るうえで必要な機能
・「追加」を押したら、TODOタスク一覧に反映されること
・反映されたTODOタスクは残り続けること
・「実行済」にしたらタスクが消えること
つまり「状態」を保持する必要がある。ReactではReact Hooksを使って状態管理を実現する。
先ほどのApp.js
に直接書いてみた。
import { useState } from 'react';
function App() {
/**
* todo = ステートの値
* setTodo = ステートの値を更新するメソッド
*/
const [todo, setTodo] = useState(``)
const [todoList, setTodoList] = useState([]);
// TODOリストに入力項目を追加する関数
const addTodoList = () => {
if (!todo) return
const newTodoList = [todo];
// 配列(オブジェクト)に対して"イミュータブル"な操作で追加する
setTodoList([newTodoList, ...todoList]);
setTodo(``);
}
return (
<div>
<h1>TODOタスク一覧</h1>
<ul>
{todoList.map((item) => {
return <li>{item}</li>
})}
</ul>
<form onSubmit={(e) => {
e.preventDefault();
addTodoList();
}}>
<input
type="text"
value={todo}
onChange={(e) => setTodo(e.target.value)}
/>
<input
type="submit"
value="追加"
// addTodoList関数そのもの渡す。
// 実行自体はform要素のonSubmit()で実施する
onSubmit={addTodoList}
/>
</form>
</div>
);
}
export default App;