Learn React
セットアップ
code:sh
cd ~/src
npx create-react-app learn-react
起動
code:sh
cd learn-react
npm start
https://gyazo.com/da402276a34b5dc1fd642e650fd7a3a2
Qick Start
基本的な事項
Creating and nesting components
入れ子になったコンポーネント。
code:src/App.js
function MyButton() {
return (
<button>
I'm a button
</button>
);
}
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
以下が表示される
https://gyazo.com/9edb7cd61c1975963985f70a3256f60b
スタイルの指定
code:src/index.css
.avatar {
border-radius: 50%;
}
code:App.js
const user = {
name: 'はたけやまたかし',
imageSize: 90,
};
export default function Profile() {
return (
<>
<h1>{user.name}</h1>
<img
className="avatar"
src={user.imageUrl}
alt={'Photo of' + user.name}
style={{
width: user.imageSize,
height: user.imageSize,
}}
</img>
</>
);
}
index.cssの読み込みはindex.jsで行われている
code:src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css'; // ここで index.css を読み込んでる
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
以下が表示される
https://gyazo.com/65c5400fd0b86bf0828129ba5fe52e17
条件によるレンダリングの出し分け
if文を使う場合
code:js
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
三項演算子を使う場合
code:js
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
elseが不要な場合
code:js
<div>
{isLoggedIn && <AdminPanel />}
</div>
リストのレンダリング
code:src/App.js
const products = [
{title: 'キャベツ', isFruit: false, id: 1},
{title: 'ニンニク', isFruit: false, id: 2},
{title: 'リンゴ', isFruit: true, id: 3},
];
export default function ShoppingList() {
const listItems = products.map((e) =>
<li
key={e.id}
style={{
color: e.isFruit ? 'magenta' : 'darkgreen'
}}
{e.title}
</li>
);
return (
<ul>{listItems}</ul>
);
}
以下のようなリストが表示される。
https://gyazo.com/ac7ee898cd73dfcf14b8b82e3e8cdde0
li要素にkey属性を付けないと以下のような警告が出る。productsが更新された時にどの要素を再描画するかどうかの判定に必要なので何かしらの値をセットしてあげること。
https://gyazo.com/ce56ffb871cdd0b0b50988567ba934e2
イベントへの応答
code:src/App.js
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button
onClick={handleClick}
Click me
</button>
);
}
export default function MyApp() {
return (
<>
<h1>Hello</h1>
<MyButton />
</>
);
}
ボタンを押すと以下のようなアラートが表示される。
https://gyazo.com/78a6fb2b6ec145cb683bbae4568bb0c1
表示情報の更新
コンポーネントの内部でステートを管理したい場合は useState を利用する。
code:src/App.js
import { useState } from 'react';
function MyButton() {
function handleClick() {
setCount(count + 1);
}
return (
<button
onClick={handleClick}
Clicked {count} times
</button>
);
}
export default function MyApp() {
return (
<>
<h1>Hello</h1>
<MyButton />
</>
);
}
ボタンをクリックするたびにカウントが増えていく。
https://gyazo.com/a579dd16786274dd7142dbede816267d
Using Hooks
関数名が use で始まっている関数は Hooks と呼ばれる。useStateはReactビルトインのフック。
他のHooksはこちらから探すことができる。
React API reference
フックは通常の関数よりも制限が厳しく、コンポーネントのトップレベルか、または他のフックからしか呼び出すことができない(???)条件分岐やループの中でuseStateを使いたい場合は新しいコンポーネントとして切り出す必要がある(???)
(だめな状況がうまくイメージできない...)
コンポーネント間のデータの共有
MyButtonへ持たせていたステートとhandleClickをMyAppへ移動し、ふたつのMyButtonの間でステートを共有するようにする。
code:src/App.js
import { useState } from 'react';
function MyButton({count, onClick}) {
return (
<div>
<button
onClick={onClick}
Clicked {count} times
</button>
</div>
);
}
export default function MyApp() {
// MyButtonからMyAppへステートを移動
// MyButtonからMyAppへhandleClickを移動
function handleClick() {
setCount(count + 1);
}
// MyButtonへcountとonClickを渡す
return (
<>
<h1>Hello</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</>
);
}
こんな画面が出力される。
https://gyazo.com/468a720a34a5b60f8401883f27ab0f12