node.jsで色々とインストールするのが面倒なので、コピペOKなCDN(ライブラリURL指定)でreactを学んでみる。
0, とりあえず、hello,world
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React Test</title> </head> <body> <div id="root"></div> <!-- reactのライブラリ --> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <!-- ReactDOMライブラリ --> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <!-- Babelライブラリ(トランスパイス=各ブラウザに最適なJSに書き換えてくれる) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.10.3/babel.min.js"></script> <!-- typeがtext/javascriptじゃなくてtext/babelな事に注意!!! --> <script type="text/babel"> // ブラウザ上に描写 ReactDOM.render( <h1>Hello world!!!!!!!</h1>, // 内容 document.getElementById('root') // 出力先 ); </script> </body> </html> |
1, コンポーネント(部品化)とプロップス(状態の保持)の簡単なreactサンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React Sample</title> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> // Greeting コンポーネントの定義 function Greeting(props) { return <h1>Hello, {props.name}!</h1>; } // App コンポーネントで Greeting コンポーネントを使用 function App() { return ( <div> <Greeting name="Alice" /> <Greeting name="Bob" /> <Greeting name="Charlie" /> </div> ); } // App コンポーネントをDOMにレンダリング ReactDOM.render(<App />, document.getElementById('root')); </script> </body> </html> |
コンポーネントが関数で、タグで定義された所でコールされる
プロップスが関数の引数、タグの属性が使われる。
Appのタグの形で、App関数をコールするのって変な感じ。
クォーテーションで囲まなくてもいいいんだ。
functionで関数test()を定義して、タグ
さらに、test(props)と定義すると、タグ
reactコンポーネントの名前は、必ず頭文字が大文字でないと駄目!
これはReactがコンポーネントとHTMLタグを区別するためのルールです。
逆も言うと、htmlタグは必ず小文字じゃないと、reactコンポーネントと解釈される。
2. コンポーネントの状態(State)とイベント処理(ボタンを押されたらonClickで関数コール)
1, Counterタグで、Counter関数をコール
2, React.useState(0)で初期値を0に指定。useStateフックという機能を使って、状態を変化させる関数setCountと、値を保持する変数countを設定
3, increment関数で、count+1
4, イベント処理(ボタンを押されたらonClickでincrement関数をコール)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Counter App</title> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> // Counter コンポーネントの定義 function Counter() { // useStateフックという機能を使って、状態を変化させる関数setCountと、値を保持する変数countを設定 // React.useState(0)で初期値を0に指定 const [count, setCount] = React.useState(0); // カウントアップする関数 function increment() { setCount(count + 1); } return ( <div> <h1>Count: {count}</h1> <button onClick={increment}>Increment</button> </div> ); } // Counter コンポーネントを DOM にレンダリング ReactDOM.render(<Counter />, document.getElementById('root')); </script> </body> </html> |
3. ライフサイクルメソッド
コンポーネント(部品)の初期化→表示→更新→削除(非表示)のそれぞれのタイミングで関数コールできるので、それぞれの処理を追加してね
constructor: コンポーネントが作成されるときに最初に呼ばれます。状態の初期設定やプロパティのバインディングに使用されます。
マウンティング(表示)のフェーズ
componentDidMount: コンポーネントがDOMに挿入された後に呼ばれます。APIからデータをフェッチしたり、他のJavaScriptフレームワークやライブラリとのインテグレーションを行ったりするのに適しています。
アップデートのフェーズ
componentDidUpdate: コンポーネントが更新された後に呼ばれます。新しいプロップスや状態に基づいて必要なDOMのアップデートを行ったり、追加のリクエストを行うことができます。
アンマウンティング(削除/非表示)のフェーズ
componentWillUnmount: コンポーネントがDOMから削除される直前に呼ばれます。ここで、イベントリスナーの解除やタイマーのクリアなど、クリーンアップを行うことが重要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React Lifecycle Demo</title> </head> <body> <div id="root"></div> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <!-- Babel の追加 --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> 'use strict'; class LifecycleDemo extends React.Component { constructor(props) { super(props); console.log('Constructor: コンポーネントが初期化されます。'); this.state = { count: 0 }; // 状態の初期化 } componentDidMount() { console.log('componentDidMount: コンポーネントがマウントされました。'); } componentDidUpdate() { console.log('componentDidUpdate: コンポーネントが更新されました。'); } componentWillUnmount() { console.log('componentWillUnmount: コンポーネントがアンマウントされる前に呼び出されます。'); } increment = () => { this.setState({ count: this.state.count + 1 }); } render() { console.log('Render: UIが描画されます。'); return ( <div> <h1>Count: {this.state.count}</h1> <button onClick={this.increment}>Increment</button> </div> ); } } ReactDOM.render(<LifecycleDemo />, document.getElementById('root')); </script> </body> </html> |
5. 条件付きレンダリング
特定の条件に基づいて異なるコンポーネントを表示する方法です。
メッセージが表示されていなければ表示ボタン
表示されていたら、隠すボタン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React Conditional Rendering Example</title> <!-- ReactとReactDOMのCDNからの読み込み --> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <!-- BabelのCDNからの読み込み。JSXをブラウザで解釈するために必要 --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <!-- Reactアプリケーションを埋め込むためのルート要素 --> <div id="root"></div> <script type="text/babel"> // App関数コンポーネントの定義 function App() { // メッセージの表示/非表示を制御するための状態変数showMessage const [showMessage, setShowMessage] = React.useState(false); // showMessageの値をトグルする関数 function toggleMessage() { setShowMessage(!showMessage); } // コンポーネントのUIを返す部分 return ( <div> {/* メッセージの表示/非表示を切り替えるボタン */} <button onClick={toggleMessage}> {showMessage ? 'Hide' : 'Show'} Message </button> {/* 条件付きでメッセージを表示。showMessageがtrueの場合のみ表示される */} {showMessage && <p>Hello, this is a conditional message!</p>} </div> ); } // ReactDOMを使ってAppコンポーネントをページにレンダリング ReactDOM.render(<App />, document.getElementById('root')); </script> </body> </html> |
6. リストとキー
いわゆる配列だけど、キーで更新状態・再描写を把握している?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React List and Key Example</title> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function NumberList(props) { const numbers = props.numbers; // 親コンポーネントから渡された数値のリストを受け取る // リストアイテムをマップして、各アイテムに対して <li> タグを作成 const listItems = numbers.map((number) => // キーはReactが要素を追跡しやすくするために必要 <li key={number.toString()}> {number} </li> ); // 作成したリストアイテムを <ul> の中でレンダリング return ( <ul>{listItems}</ul> ); } const numbers = [1, 2, 3, 4, 5]; // 数値の配列 // NumberList コンポーネントをレンダリングし、numbers 配列を props として渡す ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById('root')); </script> </body> </html> |
7. フック(Hooks)
なにかが起こったら、自動的にコールされる関数の仕組み
State Hooks: ユーザーの入力情報を記録する
Effect Hooks: 外部システムとの同期、イベントリスナ
Context Hooks: 親の変数を子コンポーネントで受け取る
Ref Hooks: レンダリングに使用しない情報を記録
Performance Hooks: 再レンダリングのパフォーマンス最適化
Other Hooks: ライブラリ開発時に利用されるHooks
Your own Hooks: 独自定義によるカスタムフック
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>React Hooks Example</title> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> const UserContext = React.createContext(); // Contextの作成 function App() { const [name, setName] = React.useState(''); // State Hooks const nameRef = React.useRef(); // Ref Hooks React.useEffect(() => { // Effect Hooks nameRef.current.focus(); // inputにフォーカスを当てる console.log("Effect ran"); return () => console.log("Cleanup"); // Cleanup function }, []); // 空の依存配列でマウント時のみ実行 const memoizedNameLength = React.useMemo(() => { // Performance Hooks return name.length; // 名前の長さを計算 }, [name]); return ( <UserContext.Provider value={name}> {/* Context Hooks */} <input ref={nameRef} type="text" value={name} onChange={e => setName(e.target.value)} placeholder="Enter your name" /> <p>Name Length: {memoizedNameLength}</p> <ChildComponent /> </UserContext.Provider> ); } function ChildComponent() { const name = React.useContext(UserContext); // Context Hooks return <p>Received in child: {name}</p>; } ReactDOM.render(<App />, document.getElementById('root')); </script> </body> </html> |