Open17
Reactについて調べたこと
Sandbox的にindex.htmlで記述する方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
'use strict';
{
const container = document.getElementById('container');
const root = ReactDOM.createRoot(container);
root.render(
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
}
</script>
</body>
</html>
JSX記法
- 単一のルート要素を返す。複数返したい場合は<React.Fragment>もしくは<>で囲む。
<>
</>
- すべてのタグを閉じる
- キャメルケースで記述する。
- babel/standaloneでトランスコンパイルできる。<script type="text/babel">の記述でコンパイルされる。
- JavaScriptの式は{}で囲んで記述することができる。bool型は何も出力されない。
式と分の違いは、式は値を返す。文は変数宣言、for・if・swtich文など。
1
は式文。 - JSX - babel -> JSオブジェクト -> React要素のように変換される。
CSSのclassについて
- classNameで記述する
<div className="class1">
</div>
コンポーネント
const App = () => {
return (
<>
</>
);
};
prosで値を受け取る、{}で囲って値を表示する
- 通常の受け方
<script type="text/babel">
'use strict';
{
const container = document.querySelector('#container');
const root = ReactDOM.createRoot(container);
const Item = (props) => {
return (
<li>{props.value}</li>
);
}
const App = () => {
return (
<>
<div>
<ul>
<Item value="Hello" />
<Item value="World" />
<Item value="React" />
</ul>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
</>
);
};
root.render(<App />);
}
</script>
- 分割代入
const Item = ({value}) => {
- 分割代入(デフォルト値有)
const Item = ({value = 'hello'}) => {
- 分割代入(デフォルト値有、変数のリネーム)
const Item = ({value: v = 'hello'}) => {
- 関数を渡す。
- boolを渡す。
- オブジェクトを渡す。
- split演算子(...foo)で渡す。
配列をmapしてコンポーネント生成
const ItemValues = ['Hello', 'World', 'React'];
ItemValues.map((value) => {
const Item = (props) => {
return (
<li>{props.value}</li>
);
}
root.render(<Item value={value} />);
});
値を保持するコンポーネント
- React.useState()で定数名と操作する関数を返してくれる。constで宣言する。
const [count, setCount] = React.useState(0);
const decrement = () => {
if(count > 0) {
setCount(count - 1);
}
};
const increment = () => setCount(count + 1);
<button onClick={decrement}>-</button>
<button onClick={increment}>+</button>
メモ:再レンダリングの条件はstate、propsが更新された時、親コンポーネントが再レンダリングされた時。
- 連続して操作関数を呼び出す場合、非同期での呼び出しのため外から変数を渡すのではなく前回の値を保持する値を取り出して、そこに値の操作を行う。
setCount(count + 1);
setCount((previousCount) => previousCount + 1);
setCount((previousCount) => previousCount + 1);
const ItemValues = [
{id: 0, name: 'Item1', value: 100},
{id: 1, name: 'Item2', value: 150},
{id: 2, name: 'Item3', value: 200},
];
const Item = (props) => {
const increment = () => {
props.onIncrement(props.id);
}
return (
<li>
{props.name} |
{props.value}
<button onClick={increment}>+</button>
</li>
);
};
const App = () => {
const [counts, setCounts] = React.useState([0, 0, 0]);
const increment = (id) => {
const newCounts = [...counts];
console.log(newCounts);
newCounts[id] += 1;
console.log(newCounts);
setCounts(newCounts);
console.log('increment');
}
const Items = () => {
const itemValuesComponent = ItemValues.map((item) => {
return (
<Item
key={item.id}
id={item.id}
name={item.name}
value={counts[item.id]}
onIncrement={increment} />
);
})
return itemValuesComponent;
};
return (
<div>
<h1>Shopping Cart</h1>
<ul>
<Items />
</ul>
</div>
)
}
JavaSctriptの基礎
-
ブラウザでのデバック
debuggerと記述するとブラウザでデバックできる。 -
import/export
- export defaultの宣言はファイルに1つ
- 最後にまとめてexportするのは名前付きexport
- export defaultしたものをimportするには名前を付ける。{}は必要ない。
import foo from './foo.js'
- typeだけをimportする場合
import type { foo } from './foo.js'
React Developer Tools
- Components
Componentのツリーを確認できる
propsとしてわたってくるデータを確認できる。編集できる。
ソースに飛ぶこともできる
歯車アイコンから「Highlight updates when components render.」にチェックを入れると再レンダリングの個所が分かる。 - Profiler
レンダリングの内容と時間
検索テクニック
- after:2024
- site: or damain:
- foo * baseのようにアスタリスク
TypeScript
- プロジェクト作成
npx create-react-app project-name --template typescript
- リテラル型
let hello: 'hello' = 'hello';
type DayOfWeek =
| 'Monday'
| 'Truesday'
※最初のパイプは無視される。
Type
- 関数の型定義とは
Type FuncDefine = (x: number, y: number): number;
const func: FuncDefine = (x, y) => x + y;
関数の引数と戻り値の型定義のみを行える。
React.FC
- Reactの関数コンポーネント(FunctionComponent)
React.ReactNode
- propsに型定義
type FooProps = {
name : string,
children: React.ReactNode,
fn: (text: string) -> void
}
const Bar: React.FC<FooProps> = (props) => {
return (
<>
<div>
Hello {props.name} {props.children}
</div>
</>
)
}
Eventタイプ
- React.ChangeEvent
- React.MouseEvent
SynthetricEventを継承している。
useStateに型定義
type User{
name: string,
age: number
}
const [users, setUsers] = useState<User[]>([{name: "name1", age: 23}])