React 関数共有方法解説
React アプリケーションにおいて、複数のコンポーネント間で関数を共有する方法はいくつかあります。以下に、一般的な手法をいくつか紹介します。
関数を直接インポートする
- 独立した関数やユーティリティ関数に適している
- シンプルで直接的な方法
// utils.js
export const myFunction = () => {
// 関数のロジック
};
// ComponentA.js
import { myFunction } from './utils';
// ComponentB.js
import { myFunction } from './utils';
関数を高階コンポーネントとしてラップする
- コンポーネントのレンダリングロジックをカスタマイズできる
- 複数のコンポーネントに共通の機能を提供する場合に有用
// HigherOrderComponent.js
const withMyFunction = (WrappedComponent) => {
return (props) => {
const myFunction = () => {
// 関数のロジック
};
return <WrappedComponent {...props} myFunction={myFunction} />;
};
};
// ComponentA.js
import withMyFunction from './HigherOrderComponent';
const ComponentA = withMyFunction(() => {
// コンポーネントのレンダリングロジック
});
Context API を使用する
- グローバルな状態管理に適している
- 複数のレベルのネストされたコンポーネント間でデータを共有する場合に便利
// MyContext.js
import React, { createContext, useContext, useState } from 'react';
const MyContext = createContext();
export const MyProvider = ({ children }) => {
const [ sharedState, setSharedState] = useState();
const sharedFunction = () => {
// 関数のロジック
};
return (
<MyContext.Provider value={{ sharedState, sharedFunction }}>
{children}
</MyContext.Provider>
);
};
export const useMyContext = () => useContext(MyContext);
// ComponentA.js
import { useMyContext } from './MyContext';
const ComponentA = () => {
const { sharedFunction } = useMyContext();
// sharedFunction を使用
};
適切な方法を選択する際の考慮事項
- グローバルな状態管理
Context API はグローバルな状態や関数を共有する場合に適している。 - コンポーネント間の関係
高階コンポーネントは複数のコンポーネントに共通の機能を提供する場合に有効。 - 関数の独立性
独立した関数やユーティリティ関数は直接インポートがシンプル。
export const myFunction = () => {
console.log('This is a shared function.');
};
ComponentA.js
import React from 'react';
import { myFunction } from './utils';
const ComponentA = () => {
return (
<button onClick={myFunction}>Click me</button>
);
};
export default ComponentA;
import React from 'react';
import { myFunction } from './utils';
const ComponentB = () => {
return (
<div>
<button onClick={myFunction}>Click me too</button>
</div>
);
};
export default ComponentB;
高階コンポーネントを使用する
HigherOrderComponent.js
const withMyFunction = (WrappedComponent) => {
return (props) => {
const myFunction = () => {
console.log('Shared function from HOC');
};
return <WrappedComponent {...props} myFunction={myFunction} />;
};
};
export default withMyFunction;
import React from 'react';
import withMyFunction from './HigherOrderComponent';
const ComponentA = (props) => {
return (
<button onClick={props.myFunction}>Click me</button>
);
};
export default withMyFunction(ComponentA);
MyContext.js
import React, { createContext, useContext, useState } from 'react';
const MyContext = createContext();
export const MyProvider = ({ children }) => {
const [ sharedState, setSharedState] = useState();
const sharedFunction = () => {
console.log('Shared function from Context API');
};
return (
<MyContext.Provider value={{ sharedState, sharedFunction }}>
{children}
</MyContext.Provider>
);
};
export const useMyContext = () => useContext(MyContext);
import React from 'react';
import { useMyContext } from './MyContext';
const ComponentA = () => {
const { sharedFunction } = useMyContext();
return (
<button onClick={sharedFunction}>Click me</button>
);
};
export default ComponentA;
- 複雑なロジックをシンプルに管理
- 再利用可能な関数ロジックをカプセル化
import { useState, useEffect } from 'react';
const useSharedFunction = () => {
const [sharedState, setSharedState] = useState();
const sharedFunction = () => {
// 関数のロジック
};
useEffect(() => {
// サイドエフェクト
}, []);
return { sharedState, sharedFunction };
};
// ComponentA.js
import { useSharedFunction } from './myHook';
const ComponentA = () => {
const { sharedFunction } = useSharedFunction();
return (
<button onClick={sharedFunction}>Click me</button>
);
};
Render Props
- 柔軟なデータの受け渡しとレンダリングが可能
- コンポーネント間でデータを共有し、子コンポーネントのレンダリングを制御
const SharedFunctionProvider = ({ children }) => {
const sharedFunction = () => {
// 関数のロジック
};
return children({ sharedFunction });
};
// ComponentA.js
const ComponentA = () => {
return (
<SharedFunctionProvider>
{(props) => (
<button onClick={props.sharedFunction}>Click me</button>
)}
</SharedFunctionProvider>
);
};
- コンポーネント間の関係
Render Props は親子関係のコンポーネント間でデータとレンダリングを制御する場合に有効。 - データの共有範囲
グローバルな共有には Context API が適している。 - 関数の複雑さ
複雑なロジックは Custom Hooks でカプセル化するとわかりやすくなる。
reactjs