[解決済み] フックで要素の配列に複数のrefを使用するにはどうすればよいですか?
2022-04-29 08:31:19
質問
私が理解する限り、私はこのように単一の要素にrefsを使用することができます。
const { useRef, useState, useEffect } = React;
const App = () => {
const elRef = useRef();
const [elWidth, setElWidth] = useState();
useEffect(() => {
setElWidth(elRef.current.offsetWidth);
}, []);
return (
<div>
<div ref={elRef} style={{ width: "100px" }}>
Width is: {elWidth}
</div>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
これを要素の配列に対して実装するにはどうしたらよいでしょうか。明らかに違いますね。(試さないでも分かってました:)
const { useRef, useState, useEffect } = React;
const App = () => {
const elRef = useRef();
const [elWidth, setElWidth] = useState();
useEffect(() => {
setElWidth(elRef.current.offsetWidth);
}, []);
return (
<div>
{[1, 2, 3].map(el => (
<div ref={elRef} style={{ width: `${el * 100}px` }}>
Width is: {elWidth}
</div>
))}
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
私が見たのは これ であり、それゆえ これ . しかし、この単純なケースでその提案をどのように実装すればいいのか、まだ迷っています。
どのように解決するのですか?
参照は、最初は単なる
{ current: null }
オブジェクトを作成します。
useRef
は、コンポーネントのレンダリング間でこのオブジェクトへの参照を保持します。
current
の値は、主にコンポーネント参照用に意図されているが、何でも保持することができる。
ある時点で、refの配列が存在するはずです。配列の長さがレンダリングごとに異なる場合、配列はそれに応じてスケールする必要があります。
const arrLength = arr.length;
const [elRefs, setElRefs] = React.useState([]);
React.useEffect(() => {
// add or remove refs
setElRefs((elRefs) =>
Array(arrLength)
.fill()
.map((_, i) => elRefs[i] || createRef()),
);
}, [arrLength]);
return (
<div>
{arr.map((el, i) => (
<div ref={elRefs[i]} style={...}>
...
</div>
))}
</div>
);
このコード片は、アンラップすることで最適化することができます。
useEffect
に置き換えて
useState
を
useRef
しかし、レンダー関数で副作用を行うことは、一般的にバッドプラクティスであると考えられていることに注意する必要があります。
const arrLength = arr.length;
const elRefs = React.useRef([]);
if (elRefs.current.length !== arrLength) {
// add or remove refs
elRefs.current = Array(arrLength)
.fill()
.map((_, i) => elRefs.current[i] || createRef());
}
return (
<div>
{arr.map((el, i) => (
<div ref={elRefs.current[i]} style={...}>
...
</div>
))}
</div>
);
関連
-
JavaScriptのクロージャの説明
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで空文字列/未定義文字列/null文字列をチェックするにはどうすればよいですか?
-
[解決済み] オブジェクトが配列であるかどうかを確認するにはどうすればよいですか?[重複]。
-
[解決済み] JavaScriptで要素のクラスを変更するにはどうすればよいですか?
-
[解決済み] jQueryでページを更新するにはどうすればよいですか?
-
[解決済み] JavaScriptで配列の先頭に新しい配列要素を追加するにはどうすればよいですか?
-
[解決済み] JavaScriptで2次元の配列を作成するにはどうすればよいですか?
-
[解決済み] 新しい配列を作成せずに、既存のJavaScript配列を別の配列で拡張する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
jQueryのコピーオブジェクトの説明
-
Vueにシンプルなメモ帳機能を実装
-
vueにおけるv-forループオブジェクトのプロパティ
-
vueが定義するプライベートフィルタと基本的な使い方
-
VUEグローバルフィルターの概念と留意点、基本的な使い方
-
[解決済み】awaitは非同期関数でのみ有効です。
-
[解決済み] Web API エラー - このリクエストはブロックされました; コンテンツは HTTPS で提供されなければなりません
-
[解決済み】 `string.split is not a function` というエラーの原因は何ですか?
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
Uncaught TypeError: null のプロパティ 'offsetHeight' を読み取れませんでした。