Reactコンポーネント間通信をレベルアップ!カスタムイベントリスナーで実現する高度な連携
ReactJS コンポーネントにカスタムイベントリスナーを追加する方法
カスタムイベントリスナーを追加するには、以下の手順に従います。
- イベント名を定義する: まず、コンポーネント内で発生するカスタムイベントの名前を定義する必要があります。この名前は、イベントを発行するコンポーネントと、イベントを処理するコンポーネントの間で共有されます。
- イベントハンドラを作成する: 次に、イベントが発生したときに実行されるイベントハンドラを作成する必要があります。このハンドラは、イベントオブジェクトを引数として受け取り、イベントデータにアクセスすることができます。
- イベントリスナーを追加する: 最後に、イベントリスナーをコンポーネントに追加する必要があります。これには、
addEventListener()
メソッドを使用します。このメソッドには、イベント名とイベントハンドラを引数として渡します。
例
以下の例は、MyComponent
というコンポーネントに myCustomEvent
というカスタムイベントリスナーを追加する方法を示しています。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
handleClick = () => {
this.setState((prevState) => ({ count: prevState.count + 1 }));
this.dispatchEvent(new CustomEvent('myCustomEvent', { detail: { count: this.state.count } }));
};
render() {
return (
<div>
<button onClick={this.handleClick}>Click me</button>
<p>Count: {this.state.count}</p>
</div>
);
}
}
この例では、handleClick()
メソッドがクリックされたときに呼び出され、myCustomEvent
イベントが発行されます。このイベントには、count
プロパティを持つ詳細オブジェクトが渡されます。
イベントリスナーの処理
コンポーネントで myCustomEvent
イベントを処理するには、以下の手順に従います。
- イベントリスナーを追加する:
addEventListener()
メソッドを使用して、イベントリスナーをコンポーネントに追加します。このメソッドには、イベント名とイベントハンドラを引数として渡します。
例
class MyOtherComponent extends React.Component {
componentDidMount() {
window.addEventListener('myCustomEvent', this.handleMyCustomEvent);
}
componentWillUnmount() {
window.removeEventListener('myCustomEvent', this.handleMyCustomEvent);
}
handleMyCustomEvent = (event) => {
console.log('myCustomEvent was fired:', event.detail.count);
};
render() {
return <div>I am listening for myCustomEvent</div>;
}
}
この例では、componentDidMount()
メソッド内で myCustomEvent
イベントのリスナーが追加されます。このリスナーは、handleMyCustomEvent()
メソッドによって処理されます。このメソッドは、イベントオブジェクトを受け取り、イベントデータにアクセスします。
ReactJS コンポーネントにカスタムイベントリスナーを追加することで、コンポーネント間の通信や、コンポーネント内での特定の動作をトリガーすることができます。これは、複雑な React アプリケーションを構築する際に役立つ強力なツールです。
MyComponent.js
import React, { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount((prevState) => prevState + 1);
const customEvent = new CustomEvent('myCustomEvent', { detail: { count } });
window.dispatchEvent(customEvent);
};
return (
<div>
<button onClick={handleClick}>Click me</button>
<p>Count: {count}</p>
</div>
);
};
export default MyComponent;
import React, { useEffect } from 'react';
const MyOtherComponent = () => {
useEffect(() => {
const handleMyCustomEvent = (event) => {
console.log('myCustomEvent was fired:', event.detail.count);
};
window.addEventListener('myCustomEvent', handleMyCustomEvent);
return () => {
window.removeEventListener('myCustomEvent', handleMyCustomEvent);
};
}, []);
return <div>I am listening for myCustomEvent</div>;
};
export default MyOtherComponent;
App.js
import React from 'react';
import MyComponent from './MyComponent';
import MyOtherComponent from './MyOtherComponent';
const App = () => {
return (
<div>
<MyComponent />
<MyOtherComponent />
</div>
);
};
export default App;
このコードを実行すると、MyComponent
コンポーネントのボタンをクリックすると、myCustomEvent
イベントが発行されます。このイベントは、MyOtherComponent
コンポーネントによって処理され、コンソールにイベントの詳細情報が出力されます。
解説
- MyComponent.js:
useState
フックを使用して、count
ステートを定義します。
- MyOtherComponent.js:
このサンプルコードは、ReactJS コンポーネントにカスタムイベントリスナーを追加する方法を理解するための出発点として使用できます。
ReactJS コンポーネントにカスタムイベントリスナーを追加するその他の方法
高階コンポーネントを使用して、コンポーネントにカスタムイベントリスナーを追加することができます。高階コンポーネントは、既存のコンポーネントをラップして、その機能を拡張するために使用されます。
import React from 'react';
const withMyCustomEventListener = (WrappedComponent) => {
return class extends React.Component {
componentDidMount() {
window.addEventListener('myCustomEvent', this.handleMyCustomEvent);
}
componentWillUnmount() {
window.removeEventListener('myCustomEvent', this.handleMyCustomEvent);
}
handleMyCustomEvent = (event) => {
console.log('myCustomEvent was fired:', event.detail.count);
};
render() {
return <WrappedComponent {...this.props} />;
}
};
};
const MyComponentWithEventListener = withMyCustomEventListener(MyComponent);
この例では、withMyCustomEventListener
という高階コンポーネントが定義されています。このコンポーネントは、引数としてラップするコンポーネントを受け取り、新しいコンポーネントを返します。新しいコンポーネントは、ラップされたコンポーネントのすべての機能に加えて、myCustomEvent
イベントのリスナーも備えています。
renderProps
を使用して、コンポーネントにカスタムイベントリスナーを追加することができます。renderProps
は、コンポーネントにレンダリングされるプロパティのオブジェクトです。
import React from 'react';
const MyComponent = ({ onClick, count }) => {
return (
<div>
<button onClick={onClick}>Click me</button>
<p>Count: {count}</p>
</div>
);
};
const MyOtherComponent = () => {
const [count, setCount] = useState(0);
const handleMyCustomEvent = (event) => {
setCount(event.detail.count);
};
return (
<MyComponent
onClick={() => {
const customEvent = new CustomEvent('myCustomEvent', { detail: { count } });
window.dispatchEvent(customEvent);
}}
count={count}
renderProps={{ handleMyCustomEvent }}
/>
);
};
この例では、MyComponent
コンポーネントは onClick
と count
というプロパティを受け取ります。MyOtherComponent
コンポーネントは、MyComponent
コンポーネントをレンダリングし、onClick
と count
プロパティを渡します。さらに、MyOtherComponent
コンポーネントは、handleMyCustomEvent
という新しいプロパティも渡します。このプロパティは、MyComponent
コンポーネント内で myCustomEvent
イベントを処理するために使用できます。
Context API を使用して、コンポーネント間でイベントを共有することができます。Context API は、コンポーネントツリー全体で値を共有するための仕組みです。
import React, { useContext } from 'react';
const MyCustomEventContext = React.createContext();
const MyComponent = () => {
const [count, setCount] = useState(0);
const { dispatch } = useContext(MyCustomEventContext);
const handleClick = () => {
setCount((prevState) => prevState + 1);
dispatch({ type: 'MY_CUSTOM_EVENT', count });
};
return (
<div>
<button onClick={handleClick}>Click me</button>
<p>Count: {count}</p>
</div>
);
};
const MyOtherComponent = () => {
const { dispatch } = useContext(MyCustomEventContext);
useEffect(() => {
const handleMyCustomEvent = (event) => {
console.log('myCustomEvent was fired:', event.data.count);
};
dispatch({ type: 'ADD_EVENT_LISTENER', listener: handleMyCustomEvent });
return () => {
dispatch({ type: 'REMOVE_EVENT_LISTENER', listener: handleMyCustomEvent });
};
}, []);
return <div>I am listening for myCustomEvent</div>;
};
const App = () =>
reactjs