【初心者向け】React Hooksで要素の配列に複数の参照を設定する方法
React Hooksを使って要素の配列に複数の参照を使用するには、useState
と useRef
フックを組み合わせる必要があります。
コード例
const [elements, setElements] = useState([]);
const refs = useRef([]);
const addElement = () => {
const element = document.createElement('div');
refs.current.push(element);
setElements([...elements, element]);
};
const removeElement = (index) => {
const element = refs.current[index];
element.parentNode.removeChild(element);
refs.current.splice(index, 1);
setElements([...elements.slice(0, index), ...elements.slice(index + 1)]);
};
return (
<div>
{elements.map((element, index) => (
<div key={index} ref={refs.current[index]}>
{element}
</div>
))}
<button onClick={addElement}>要素を追加</button>
<button onClick={removeElement}>要素を削除</button>
</div>
);
解説
useState
フックを使って、要素の配列 (elements
) とその配列を更新するための関数 (setElements
) を定義します。useRef
フックを使って、要素の参照を格納するための空の配列 (refs
) を定義します。addElement
関数は、新しい要素を作成し、refs.current
配列に追加し、elements
配列を更新します。render
関数は、elements
配列の各要素をレンダリングします。各要素は、refs.current
配列の対応するインデックスにある参照を使用してレンダリングされます。
この方法の利点
- 各要素に個別の参照を使用できるため、個別に操作することができます。
refs.current
配列は、要素の順序が変更されても常に最新の状態を保ちます。
useMemo
フックを使って、要素の参照を格納するオブジェクトを作成することができます。
補足
import React, { useState, useRef } from 'react';
const App = () => {
const [elements, setElements] = useState([]);
const refs = useRef([]);
const addElement = () => {
const element = document.createElement('div');
refs.current.push(element);
setElements([...elements, element]);
};
const removeElement = (index) => {
const element = refs.current[index];
element.parentNode.removeChild(element);
refs.current.splice(index, 1);
setElements([...elements.slice(0, index), ...elements.slice(index + 1)]);
};
return (
<div>
{elements.map((element, index) => (
<div key={index} ref={refs.current[index]}>
{element}
</div>
))}
<button onClick={addElement}>要素を追加</button>
<button onClick={removeElement}>要素を削除</button>
</div>
);
};
export default App;
このコードは、上記の解説に基づいて作成されたサンプルコードです。
実行方法
このコードを実行するには、次の手順が必要です。
-
プロジェクトフォルダを作成し、そこに次のファイルを作成します。
index.js
package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "My React app",
"main": "index.js",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
npm install
- 次のコマンドを実行して、アプリを起動します。
npm start
アプリが起動すると、ブラウザに次の画面が表示されます。
要素を追加
要素を削除
要素の追加
「要素を追加」ボタンをクリックすると、新しい要素が追加されます。
要素の削除
確認
ブラウザの開発者ツールを使用して、refs.current
配列と elements
配列の内容を確認することができます。
このサンプルコードは、基本的な例です。実際のアプリケーションでは、必要に応じてコードを修正する必要があります。
React Hooksで要素の配列に複数の参照を使用する他の方法
const refs = useMemo(() => {
return elements.map(() => useRef());
}, [elements]);
このコードは、elements
配列が変更されるたびに、新しい参照オブジェクトを作成します。
const reducer = (state, action) => {
switch (action.type) {
case 'ADD_ELEMENT':
return {
...state,
elements: [...state.elements, action.element],
refs: [...state.refs, useRef()],
};
case 'REMOVE_ELEMENT':
return {
...state,
elements: state.elements.filter((element, index) => index !== action.index),
refs: state.refs.filter((ref, index) => index !== action.index),
};
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, {
elements: [],
refs: [],
});
const addElement = (element) => {
dispatch({ type: 'ADD_ELEMENT', element });
};
const removeElement = (index) => {
dispatch({ type: 'REMOVE_ELEMENT', index });
};
このコードは、ADD_ELEMENT
と REMOVE_ELEMENT
という2つのアクションを使用して、要素の配列と参照を管理します。
カスタムフック
上記の2つの方法を組み合わせて、カスタムフックを作成することができます。
const useElements = () => {
const [elements, setElements] = useState([]);
const refs = useRef([]);
const addElement = (element) => {
refs.current.push(element);
setElements([...elements, element]);
};
const removeElement = (index) => {
const element = refs.current[index];
element.parentNode.removeChild(element);
refs.current.splice(index, 1);
setElements([...elements.slice(0, index), ...elements.slice(index + 1)]);
};
return {
elements,
refs,
addElement,
removeElement,
};
};
このカスタムフックを使用すると、他のコンポーネントから要素の配列と参照に簡単にアクセスすることができます。
- シンプルなアプリケーションであれば、
useState
フックとuseRef
フックを組み合わせる方法で十分です。 - より複雑なアプリケーションであれば、
useMemo
フックまたはuseReducer
フックを使用する方が良い場合があります。 - 再利用可能なコードを作成したい場合は、カスタムフックを作成することを検討してください。
javascript reactjs react-hooks