質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

746閲覧

Reactでmapを使って一覧表示しつつコンポーネント内でuseContextによる画像の差し替えを行いたい。

tmyk1979

総合スコア145

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/08/02 01:19

編集2022/08/02 11:00

前提

配列に画像のsrc属性の値を格納し、Reactでulの中にli、liの中にimgを配置した際、map関数でliを4つ生成しつつ、liの中のimgをそれぞれ違うものにしたいと思っています。

ulのコンポーネント内にli、imgも書き込むとindex番号をimgのsrc属性に対応させて画像を差し替える事ができたのですが、ulの中にliのコンポーネントを作り、liのコンポーネントの中にさらにimgのコンポーネントを作ると、useContextではindex番号を受け渡しできないので画像の差し替えができません。

配列にインデックス番号と同じ数を格納した変数numなどを加えずに、何とかindex番号を子や孫のコンポーネントに渡す方法はないでしょうか?

該当のソースコード

React(index.js)

1 2import React, { createContext } from 'react'; 3import ReactDOM from 'react-dom/client'; 4import './index.css'; 5import App from './App'; 6 7import relief from './components/assets/image/relief.png' 8import safety from './components/assets/image/safety.png' 9import speedy from './components/assets/image/speedy.png' 10import reasonable from './components/assets/image/reasonable.png' 11 12const featureItems = [ 13 { num: 0, name: "1.relief", alt: "relief", description: "text text text text text text text text text text text text text text text text text text text text text text text text text text text text", src: relief }, 14 { num: 1, name: "2.safety", alt: "safety", description: "text text text text text text text text text text text text text text text text text text text text text text text text text text text text", src: safety }, 15 { num: 2, name: "3.speedy", alt: "speedy", description: "text text text text text text text text text text text text text text text text text text text text text text text text text text text text", src: speedy }, 16 { num: 3, name: "4.reasonable", alt: "reasonable", description: "text text text text text text text text text text text text text text text text text text text text text text text text text text text text", src: reasonable } 17]; 18 19const featureItemsContext = createContext(featureItems) 20 21const root = ReactDOM.createRoot(document.getElementById('root')); 22 23root.render( 24 <featureItemsContext.Provider value={featureItems}> 25 <React.StrictMode> 26 <App /> 27 </React.StrictMode> 28 </featureItemsContext.Provider> 29); 30 31export default featureItemsContext; 32

React(Feature.js)

1import React from 'react' 2 3import UlClassGridCol4 from './Ul/UlClassGridCol4' 4 5function Feature() { 6 7 const innerHtml = "Feature" 8 9 return ( 10 <section className="section section-secondary"> 11 <UlClassGridCol4 /> 12 </section> 13 ) 14} 15 16export default Feature 17

React(UlClassGridCol4.js)

1import React, { useContext } from "react"; 2import featureItemsContext from "../../.."; 3 4import LiGridCol4ClassGridItem from "./Li/LiGridCol4ClassGridItem"; 5 6const UlClassGridCol4 = () => { 7 8 const featureItems = useContext(featureItemsContext); 9 10 return( 11 <ul className="grid grid-col-4"> 12 {featureItems.map((item, index) => ( 13 <React.Fragment key={item.num}> 14 <LiGridCol4ClassGridItem itemNum={item.num} /> 15 </React.Fragment> 16 ))} 17 </ul> 18 ) 19} 20 21export default UlClassGridCol4

React(LiGridCol4ClassGridItem.js)

1import React from "react"; 2 3import ImgClassFeatureImg from "./Img/ImgClassFeatureImg"; 4 5const LiGridCol4ClassGridItem = ({ itemNum }) => { 6 return( 7 <li className="grid-item"> 8 <ImgClassFeatureImg itemNum={itemNum} /> 9 </li> 10 ) 11} 12 13export default LiGridCol4ClassGridItem 14

React(ImgClassFeatureImg)

1import React, { useContext } from "react"; 2import featureItemsContext from "../../../../../index"; 3 4const ImgClassFeatureImg = ({ itemNum }) => { 5 6 const featureItems = useContext(featureItemsContext) 7 8 return( 9 <img className="feature-img" src={featureItems[itemNum].src} width="138" height="138" alt={featureItems[itemNum].alt}/> // ←←← せっかくuseContextを使ったのにitemNumをここまでバケツリレーしなくてはならないのが現状です。これをバケツリレーせずにUlClassGridCol4.js内のmapで使っている「index」とかで指定する方法はないでしょうか? 10 ) 11} 12 13export default ImgClassFeatureImg

試したこと

itemNumと書くところをfeatureItems.numとしてみましたが、ページは真っ白になり多数のエラーを吐かれてうまく行きませんでした。

せっかくuseContextを使っても、意図した通りに表示させるには一番下の階層、ImgClassFeatureImgまでitemNumをバケツリレーしなくてはならないのですが、これをバケツリレーせずにUlClassGridCol4.js内のmapで使っている「index」のような値で指定する方法はないでしょうか?

ちょっと質問内容がわかりにくくて申し訳ないのですが、分かる方がいらっしゃいましたらご教示いただきたいと思います。
宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2022/08/02 01:24

なぜ番号を引き回しているのでしょうか? (itemそのものを引き回す、という選択肢を取っていないのはどのような意図でしょうか?)
maisumakun

2022/08/02 01:28

> これをバケツリレーせずにUlClassGridCol4.js内のmapで使っている「index」のような値で指定する方法はないでしょうか? なぜそうしたいのですか?
tmyk1979

2022/08/02 01:37

すみません、番号を引き回しているというのが具体的にどこを指しているのか、また、itemそのものを引き回すというのがどうする事を指しているのか理解できませんでした。 なぜそうしたいのかというと、indexのような値で指定できればpropsのバケツリレーを一切行わず、useContextだけで画像の差し替えができ、propsのバケツリレーよりもスマートなコードになると思ったからです。
maisumakun

2022/08/02 01:43

> 番号を引き回しているというのが具体的にどこを指しているのか 「itemNumをバケツリレー」させていることです。
tmyk1979

2022/08/02 01:56

引き回すというのはバケツリレーさせている事だったのですね、分かりました。ありがとうございます。
guest

回答1

0

ベストアンサー

UlClassGridCol4.js内のmapで使っている「index」のような値で指定する方法はないでしょうか?

単にindexを使えばいいだけではないですか?

JSX

1 {featureItems.map((item, index) => ( 2 <React.Fragment key={index}> 3 <LiGridCol4ClassGridItem itemNum={index} /> 4 </React.Fragment> 5 ))}

投稿2022/08/02 01:41

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2022/08/02 01:43

> indexのような値で指定できればpropsのバケツリレーを一切行わず、useContextだけで画像の差し替えができ、 どれがどれを表示するのかの識別には、どこかでindexを流す(もしくはitemそのものをpropで流す)ことで処理を振り分ける必要があります。途中でindex用のconterxtをさらに増やすならいちおう可能ですが、「バケツリレーよりもスマートなコードになる」かは疑問です。
tmyk1979

2022/08/02 02:00 編集

indexをバケツリレーさせる事で同じ結果になるので、確かにnumをバケツリレーする必要はなかったです。 ご指摘ありがとうございます。 やはりindexならindexをバケツリレーさせなければこうした画像の差し替えは難しいのであれば、この場合コンポーネントを分ける粒度をここまで細かくせず、UlClassGridCol4.jsの中にliとimgも書いてしまった方がスマートでしょうか? そうすれば一応 ```React <img className="feature-img" src={featureItems[index].src} width="138" height="138" alt={featureItems[index].alt}/> ``` のようにindexを直接使えるのですが、コンポーネントはなるべく細かく分けた方が良いと色々な所にかかれているので、バケツリレーとどちらを取るか迷っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問