【React.js】カスタムイベントで親子のコミュニケーションを強化!データ伝達とアクション実行をスムーズに
React.jsにおけるカスタムイベントと親ノードとの通信
親ノードとの通信
カスタムイベントを使用して、子コンポーネントから親コンポーネントにデータを伝達することができます。これは、子コンポーネントが親コンポーネントの状態を変更したり、親コンポーネントにアクションを実行させたりする必要がある場合に役立ちます。
カスタムイベントの作成
カスタムイベントを作成するには、次の手順に従います。
- イベント名を定義します。これは、イベントを一意に識別するために使用されます。
- イベントデータを作成します。これは、イベントとともに伝達される任意の情報です。
- イベントオブジェクトを作成します。これは、イベント名とイベントデータを含むオブジェクトです。
dispatchEvent()
メソッドを使用して、イベントを発行します。
カスタムイベントのリスニング
親コンポーネントは、addEventListener()
メソッドを使用して、カスタムイベントをリッスンできます。
const MyComponent = () => {
const handleCustomEvent = (event) => {
const data = event.detail;
console.log(data);
};
useEffect(() => {
window.addEventListener('myCustomEvent', handleCustomEvent);
return () => window.removeEventListener('myCustomEvent', handleCustomEvent);
}, []);
return (
<div>
<ChildComponent />
</div>
);
};
const ChildComponent = () => {
const handleClick = () => {
const data = { message: 'Hello from child!' };
const event = new CustomEvent('myCustomEvent', { detail: data });
window.dispatchEvent(event);
};
return (
<button onClick={handleClick}>Click me</button>
);
};
上記の例では、ChildComponent
は myCustomEvent
というカスタムイベントを発行し、MyComponent
はそのイベントをリッスンしてコンソールにログ出力します。
カスタムイベントを使用する利点は次のとおりです。
- 再利用性
カスタムイベントは、さまざまなコンポーネントで再利用できます。 - カプセル化
コンポーネント間の通信をカプセル化することで、コードをより読みやすく、保守しやすくなります。 - 柔軟性
標準のイベントよりも柔軟にデータを送受信できます。
カスタムイベントは、さまざまな場面で使用できます。以下に、いくつかの例を示します。
- タブの切り替え
子コンポーネントから親コンポーネントにアクティブなタブを切り替えるように要求するために使用できます。 - モーダルウィンドウの開閉
子コンポーネントから親コンポーネントにモーダルウィンドウを開閉するように要求するために使用できます。 - フォームデータの送信
子コンポーネントから親コンポーネントにフォームデータを送信するために使用できます。
import React, { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<p>カウント: {count}</p>
<ChildComponent onIncrement={handleIncrement} />
</div>
);
};
export default MyComponent;
import React from 'react';
const ChildComponent = ({ onIncrement }) => {
return (
<button onClick={onIncrement}>カウントアップ</button>
);
};
export default ChildComponent;
このコードでは、MyComponent
コンポーネントは ChildComponent
コンポーネントに onIncrement
というプロップを渡します。このプロップは、ChildComponent
コンポーネントがクリックされたときに呼び出される関数です。
ChildComponent
コンポーネントは、onClick
イベントハンドラを使用して onIncrement
関数を呼び出します。これにより、MyComponent
コンポーネントの count
ステートがインクリメントされます。
このコードを実行すると、カウント: 0
というテキストが表示されます。 ChildComponent
のボタンをクリックすると、カウント
が 1 ずつインクリメントされます。
以下のコードは、カスタムイベントを使用して親ノードと子ノード間でデータをやり取りする方法を示しています。
import React, { useState } from 'react';
const MyComponent = () => {
const [message, setMessage] = useState('');
const handleReceiveMessage = (event) => {
const newMessage = event.detail;
setMessage(newMessage);
};
return (
<div>
<p>メッセージ: {message}</p>
<ChildComponent onReceiveMessage={handleReceiveMessage} />
</div>
);
};
export default MyComponent;
import React from 'react';
const ChildComponent = ({ onReceiveMessage }) => {
const handleClick = () => {
const message = 'Hello from child!';
const event = new CustomEvent('myCustomEvent', { detail: message });
window.dispatchEvent(event);
};
return (
<button onClick={handleClick}>送信</button>
);
};
export default ChildComponent;
ChildComponent
コンポーネントは、handleClick
関数を使用して myCustomEvent
というカスタムイベントを発行します。このイベントには、Hello from child!
というメッセージが含まれています。
MyComponent
コンポーネントは、addEventListener()
メソッドを使用して myCustomEvent
イベントをリッスンします。このイベントが発行されると、handleReceiveMessage
関数が呼び出され、message
ステートが更新されます。
このコードを実行すると、最初は メッセージ:
というテキストが表示されます。 ChildComponent
のボタンをクリックすると、メッセージ: Hello from child!
というテキストが表示されます。
- 子コンポーネントは、
this.props
オブジェクトを使用して props にアクセスできます。 - 親コンポーネントから子コンポーネントにデータを渡す最も単純な方法は、propsを使用することです。propsは、親コンポーネントが子コンポーネントに渡すことができるキーと値のペアの集合です。
例
// 親コンポーネント
const ParentComponent = () => {
return (
<div>
<ChildComponent message="Hello from parent!" />
</div>
);
};
// 子コンポーネント
const ChildComponent = (props) => {
return <p>{props.message}</p>;
};
Context
- Provider コンポーネントを使用して値を Context に提供し、Consumer コンポーネントを使用して値にアクセスします。
- Contextは、コンポーネントツリー全体でデータを共有するための方法です。
// Context を作成
const ThemeContext = React.createContext({ theme: 'light' });
// Provider コンポーネント
const App = () => {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div>
<ChildComponent />
</div>
</ThemeContext.Provider>
);
};
// Consumer コンポーネント
const ChildComponent = () => {
const { theme, setTheme } = React.useContext(ThemeContext);
return (
<div>
<p>現在のテーマ: {theme}</p>
<button onClick={() => setTheme('dark')}>テーマをダークに変更</button>
</div>
);
};
Redux
- Store、Actions、Reducersを使用して状態を管理します。
- Reduxは、アプリケーションの状態を管理するための単方向データフローアーキテクチャです。
// Store
const store = createStore(reducer);
// Actions
const incrementCounter = () => {
return { type: 'INCREMENT_COUNTER' };
};
// Reducers
const reducer = (state = { counter: 0 }, action) => {
switch (action.type) {
case 'INCREMENT_COUNTER':
return { counter: state.counter + 1 };
default:
return state;
}
};
// 子コンポーネントからストアにdispatch
const ChildComponent = () => {
const dispatch = useDispatch();
return (
<div>
<p>カウント: {store.getState().counter}</p>
<button onClick={() => dispatch(incrementCounter())}>カウントアップ</button>
</div>
);
};
状態を持ち上げ
- 子コンポーネントは、
props.onChange
などのコールバック関数を使用して、親コンポーネントに状態変更を通知できます。 - 状態を持ち上げることは、親コンポーネントで状態を管理し、子コンポーネントに props として渡す方法です。
// 親コンポーネント
const ParentComponent = () => {
const [count, setCount] = useState(0);
return (
<div>
<ChildComponent count={count} onChange={(newCount) => setCount(newCount)} />
</div>
);
};
// 子コンポーネント
const ChildComponent = ({ count, onChange }) => {
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => onChange(count + 1)}>カウントアップ</button>
</div>
);
};
refs
- refsを使用して、子コンポーネントから親コンポーネントのメソッドを呼び出すことができます。
- refsは、DOM要素またはコンポーネントインスタンスへの直接参照を取得する方法を提供します。
// 親コンポーネント
const ParentComponent = () => {
const childRef = useRef(null);
const handleClick = () => {
childRef.current.incrementCounter();
};
return (
<div>
<ChildComponent ref={childRef} />
reactjs