コンポーネント間通信におけるPubSubパターン
親子コンポーネント間の通信は比較的容易ですが、兄弟コンポーネント間のデータ連携には制約があります。この問題を解決するために、メッセージサブスクリプションパターンが有効です。
PubSubJSライブラリの活用
PubSubJSは軽量なメッセージバスライブラリで、以下の手順で導入できます:
npm install pubsub-js --save
import PubSub from 'pubsub-js';
実装例:コンポーネント間データ同期
コンポーネントA(データ受信側):
class ComponentA extends React.Component {
initialState = {
items: [],
initialLoad: true,
loading: false,
errorMessage: ''
};
state = this.initialState;
componentDidMount() {
this.subscriptionId = PubSub.subscribe('dataUpdate', (_, newState) => {
this.setState(newState);
});
}
componentWillUnmount() {
PubSub.unsubscribe(this.subscriptionId);
}
render() {
// レンダリングロジック
}
}
コンポーネントB(データ送信側):
class ComponentB extends React.Component {
fetchData = async (searchTerm) => {
PubSub.publish('dataUpdate', {
initialLoad: false,
loading: true
});
try {
const response = await axios.get(`/api/search?term=${searchTerm}`);
PubSub.publish('dataUpdate', {
loading: false,
items: response.data.results
});
} catch (error) {
PubSub.publish('dataUpdate', {
loading: false,
errorMessage: error.message
});
}
};
}
Fetch APIによるHTTP通信
現代的なHTTPリクエスト手法としてFetch APIが利用できます。XMLHttpRequestを置き換えるネイティブ機能で、PromiseベースのAPIを提供します。
GETリクエストの基本実装
fetch(`/api/search?query=${searchKeyword}`)
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json();
})
.then(result => {
console.log('Data retrieval successful', result);
})
.catch(error => {
console.error('Request failed', error);
});
非同期関数による最適化
const retrieveData = async (keyword) => {
try {
const response = await fetch(`/api/search?query=${keyword}`);
const jsonData = await response.json();
return jsonData;
} catch (error) {
console.error('Data fetch error', error);
throw error;
}
};
POSTリクエストの実装
const postData = async (url, payload) => {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return await response.json();
};
オブジェクト構造化の高度な技法
ネストされたオブジェクトからのデータ抽出には、連続した分割代入が有効です:
const complexObject = {
level1: {
level2: {
value: 42
}
}
};
// 従来の分割代入
const { level1 } = complexObject;
// 連続分割代入
const { level1: { level2 } } = complexObject;
// 連続分割代入+プロパティ名変更
const { level1: { level2: { value: renamedValue } } } = complexObject;