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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

React.js

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

Q&A

解決済

1回答

2129閲覧

React Map()メソッド+React-bootstrap でCarousel表示をしたい

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

React.js

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

0グッド

0クリップ

投稿2019/06/10 09:45

編集2019/06/12 03:03

前提・実現したいこと

ReactでMap()メソッドを使ってCarousel表示をするべくググり続けているのですが、
1つの画像にNext / Prevボタンが表示されてしまいうまくいきません。

やりたいこと
・横並びに表示
・はみ出たものは隠してスライドで表示
使っているもの
Node.js v10.15.3
yarn ver. 1.16.0
npm ver. 6.4.1
react-bootstrap/react-popper@1.2.1

発生している問題・エラーメッセージ

・画像ごとにNext / Prevボタンが表示される

該当のソースコード

Beach

1<Carousel className="Beach m-2"> 2 <Carousel.Item className="Carousel-img-box"> 3 <img className="Carousel-img" src={this.props.BHimg} alt="" /> 4 <Carousel.Caption className="Carousel-info text-light"> 5 <a href={this.props.BHlink} className="Carousel-link"> 6 <h3 className="Carousel-title">{this.props.BHtitle}</h3> 7 <p className="Carousel-prc">{this.props.BHprc}</p> 8 </a> 9 </Carousel.Caption> 10 </Carousel.Item> 11 </Carousel>

App

1<div className="Beaches d-flex"> 2 {BeachList.map(beachItem => { 3 return ( 4 <Beach 5 BHlink={beachItem.BHlink} 6 BHimg={beachItem.BHimg} 7 BHtitle={beachItem.BHtitle} 8 BHprc={beachItem.BHprc} 9 /> 10 ); 11 })} 12 </div>

ListData

1const BeachList = [ 2 { 3 BHlink: "#link", 4 BHimg: "./img/bch/osaka.jpg", 5 BHtitle: "Osaka", 6 BHprc: "6,160JPY/night average" 7 }, 8 { 9 BHlink: "#link", 10 BHimg: "./img/bch/kyoto.jpg", 11 BHtitle: "kyoto", 12 BHprc: "6,160JPY/night average" 13 }, 14...

試したこと

上記コンポーネントから <Carousel>だけ取り出してMap()メソッドを囲ったところ何も出てこなくなってしまいました。

App

1<Carousel className="Beaches"> 2 {BeachList.map(beachItem => { 3 return ( 4 <Beach 5 BHlink={beachItem.BHlink} 6 BHimg={beachItem.BHimg} 7 BHtitle={beachItem.BHtitle} 8 BHprc={beachItem.BHprc} 9 /> 10 ); 11 })} 12</Carousel>

補足情報(FW/ツールのバージョンなど)

以下のサイトも参考にしたのですが、コンポーネントがわかれておらず、きちんと表示されません。
CodePen

react-bootstrapのDocumentではMapを使った書き方で書いてないので参考にならず。。。
react-bootstrap Document

足りない情報があれば教えてください。

追記

ご指摘内容で修正したところ、Keyに関するAlertは消えました。
Beach.js

jsx

1<div className="Beaches d-flex"> 2 <Carousel className="Beach m-2"> 3 {BeachList.map(beachItem => { 4 return ( 5 <Beach 6 key={beachItem.BHkey} 7 BHlink={beachItem.BHlink} 8 BHimg={beachItem.BHimg} 9 BHtitle={beachItem.BHtitle} 10 BHprc={beachItem.BHprc} 11 /> 12 ); 13 })} 14 </Carousel> 15 </div>

まだ画像の表示が出ないのでもう少し調べようと思っています。
イメージ説明

追追記

画像の表示ですが、Display:noneがなぜか当たってしまっていて、うまく表示ができない状況です。
(Display:noneを外すと表示されますが全て重なって表示されるので、Activeクラスを画像のどれかに当てないといけなかったりするのでしょうか・・・?)
イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは

以下のサイトも参考にしたのですが、

ということで挙げられている CodePen のサンプルを見たうえで、ご質問のコードを拝読して、「ここを見直してみては?」と思うところを回答します。

CodePen のサンプルの中に

jsx

1const MyCarousel2 = ({ items }) => ( 2 <div className="root"> 3 <Carousel > 4 {items.map((item, i) => 5 <Carousel.Item key={i}> 6 <a className="thumbnail" href="javascript:void(0)"> 7 <img className="media-object" 8 src={item.img} 9 alt={item.alt} 10 /> 11 </a> 12 </Carousel.Item>)} 13 </Carousel> 14 </div> 15)

というコードがあります。ですので基本的な構造として、

jsx

1<Carousel> 2 <Carousel.Item> 3 ・・・ 4 </Carousel.Item> 5 <Carousel.Item> 6 ・・・ 7 </Carousel.Item> 8 9   ・・・ 10 11</Carousel>

という形で、ひとつの<Carousel>の中に複数の<Carousel.Item> が展開されています。

ですが、質問者さまのコードだと、カルーセルの1個のアイテムである <Beach /> が1個の <Carousel> になるので、以下のようなものになってしまうと思います。

jsx

1<div className="Beaches d-flex"> 2 <Carousel className="Beach m-2"> 3 <Carousel.Item className="Carousel-img-box"> 4 </Carousel.Item> 5 </Carousel> 6 <Carousel className="Beach m-2"> 7 <Carousel.Item className="Carousel-img-box"> 8 </Carousel.Item> 9 </Carousel> 10 <Carousel className="Beach m-2"> 11 <Carousel.Item className="Carousel-img-box"> 12 </Carousel.Item> 13 </Carousel> 14 15   ・・・ 16</div>

つまり、正しくは、<Carousel>の中に複数の<Carousel.Item> があるべきところが、ひとつの<Carousel.Item> を持つ <Carousel>が複数作られてしまいます。

従って、修正の方向性を示すとすれば、まず <Beach> から <Carousel> を除外して、以下のように一番外側が<Carousel.Item> になるようにします。

Beach:

jsx

1 <Carousel.Item className="Carousel-img-box"> 2 <img className="Carousel-img" src={this.props.BHimg} alt="" /> 3 <Carousel.Caption className="Carousel-info text-light"> 4 <a href={this.props.BHlink} className="Carousel-link"> 5 <h3 className="Carousel-title">{this.props.BHtitle}</h3> 6 <p className="Carousel-prc">{this.props.BHprc}</p> 7 </a> 8 </Carousel.Caption> 9 </Carousel.Item>

次にApp の修正です。
<div> の次に <Carousel> を配置し、 <Carousel>の中で map により、<Beach> の配列ができるようにします。(※以下のように return を省略して書けます。)

App:

jsx

1 <div className="Beaches d-flex"> 2 <Carousel> 3 {BeachList.map((beachItem, i) => ( 4 <Beach 5 key={i} 6 BHlink={beachItem.BHlink} 7 BHimg={beachItem.BHimg} 8 BHtitle={beachItem.BHtitle} 9 BHprc={beachItem.BHprc} 10 />) 11 )} 12 </Carousel> 13 </div>

このように修正すれば、 <Carousel> の中に複数の <Carousel.Item> が展開されるようになります。

上記の修正だけで、質問者様の要件を完全に満たすものとして動作するかは分かりませんが、以上が、今のままだと明らかに拙いと思う点とその修正の方針になります。

以上参考になれば幸いです。

追記1

上記の回答で、

javascript

1 <Carousel> 2 {BeachList.map((beachItem, i) => ( 3 <Beach 4 key={i} 5 BHlink={beachItem.BHlink} 6 BHimg={beachItem.BHimg} 7 BHtitle={beachItem.BHtitle} 8 BHprc={beachItem.BHprc} 9 />) 10 )} 11 </Carousel>

と書きましたが、 prop key に配列のインデクスを渡すのは、(CodePenのほうのサンプルコードもそうなってますが、)推奨されません。

できれば BeachList の要素に、重複しない値をもつ(id のような)プロパティを追加して、以下のようにするのがベターです。

javascript

1const BeachList = [ 2 { 3 id: 100, 4 BHlink: "#link", 5 BHimg: "./img/bch/osaka.jpg", 6 BHtitle: "Osaka", 7 BHprc: "6,160JPY/night average" 8 }, 9 { 10 id: 101, 11 BHlink: "#link", 12 BHimg: "./img/bch/kyoto.jpg", 13 BHtitle: "kyoto", 14 BHprc: "6,160JPY/night average" 15 }, 16...

javascript

1 <Carousel> 2 {BeachList.map(beachItem => ( 3 <Beach 4 key={beachItem.id} 5 BHlink={beachItem.BHlink} 6 BHimg={beachItem.BHimg} 7 BHtitle={beachItem.BHtitle} 8 BHprc={beachItem.BHprc} 9 />) 10 )} 11 </Carousel>

追記2

コメントから頂きました以下について、

Display:none;

が画像に当たってしまっているようなのですが、仕様なのでしょうか?
Documentを読み直したり、React-slickを検討してみたり、下記のように{require({this.props.BHimg})}など試してみたのですが、画像だけ表示が出ないです。。。

とのことですが、シンプルなカルーセルから初めて徐々に複雑にしいくように作業手順を見直してみてはいかがでしょうか、というのが私の提案になります。

Beach コンポーネントはが画像があったりキャプションがあったりし、かつ、様々なCSSクラスが追加されているものですが、カルーセルのライブラリを使うときにこのような、スタイル含めてかなり作り込んだものをカルーセルのアイテムとして、カルーセルのライブラリに与えても、うまく動くとは限らないのではと思います。

参考までに私がTexonさんのお作りになった現状のコードを引き継いで、カルーセルが意図通りに動くものにしていくとしたら、どのような手順でやっていくかという見通しを回答します。(以下ではReactによるSPAを想定しており、ローカルでのトップページは、 http://localhost:3000 で確認できると仮定します。)

(1) まず、カルーセルを作っていくための白紙のページを用意します。具体的には中身が空のコンテナコンポーネントを、名前は例えばCarouselTest として作成し、これが、
http://localhost:3000/spikes/carousel-test
のようなURLによってにルーティングされるようにします。spikes はスパイク(技術検証)で作ったもの、の意図です。

この時点では、 `CarouselTest` の render は、 `<div></div>` を返すだけのものです。

**(2) **上記で作った、CarouselTest の返す <div> に、以下のように <img> だけを含むアイテムを、適当な個数(以下では8個にしています)含む <Carousel> を作ります。とりあえずカルーセルが動くかだけを確認できればよいので、画像は同じものでよいですし、map を使う必要もないですので、以下のようなものでテストします。

CarouselTest: render()

<div> <Carousel> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> <Carousel.Item><img src="./img/bch/osaka.jpg" /></Carousel.Item> </Carousel> </div>

これで、http://localhost:3000/spikes/carousel-test をブラウで表示したときに、カルーセルが意図通り表示されて期待通りの動きをするかを確認します。

(3) (2) の確認がOKであれば、次にカルーセルのアイテムをひとつのコンポーネントにします。 仮に SimpleBeach とすると、

jsx

1const SimpleBeach = () => ( 2 <Carousel.Item> 3 <img src="./img/bch/osaka.jpg" /> 4 </Carousel.Item> 5)

のようなものになでしょう。これを使うと、 CarouselTest<Carousel> の中に 8個の SimpleBeach を生成するコードは以下のようになります。ここで map を使います。

CarouselTest: render()

<div> <Carousel> {[...Array(8)].map((_,i) => ( <SimpleBeach key={i} /> ))} </Carousel> </div>

上記では、配列のインデクスをkey に使っているので、警告が出ますが、スパイクで作っているものなので、後で修正すればよいのでここでは気にせずともよいでしょう。

(2) から (3) の修正では、単に <Carousel.Item> 1個分のコンポーネントを括りだしただけなので、 (2) が意図通り動くのであれば、上記も動くはずです。

**(4) **次にSimpleBeachに <Carousel.Caption> を追加します。

jsx

1const SimpleBeach = () => ( 2 <Carousel.Item> 3 <img src="./img/bch/osaka.jpg" /> 4 <Carousel.Caption> 5 <p>osaka</p> 6 </Carousel.Caption> 7 </Carousel.Item> 8)

ここでは、 <p>osaka</p> をキャプションの中身にしました。これで動くかを確認します。

このようにして、白紙のページにもっともシンプルな <Carousel> を作ってそれを出発点にして、ちょっとした変更、追加を加えるたびに動作確認をしていきます。このような作業をやっていってCSSクラスをあてるなどして、もともとの <Beach> に近づけていったときに、どこかで不具合が起きるかもしれません。カルーセルのライブラリが各アイテムに付与しているクラスだったりスタイルなどが、独自に与えたデザインのためのクラスによるスタイルと干渉しあって、うまくカルーセルが動かなくなることも考えられます。このように、シンプルでデザインは何もあたっていないがカルーセルとして動くということを確認しながら、<BeachSimple> を少しずつ複雑にしていくように進めていけば、どこで動かなくなるかが特定できます。このやり方では、どんな小さな修正を加えても動くことを確認しながら進めることが肝心です。

なおこのような作業をやるときは Git などのバージョン管理システムが便利です。この場合であれば、カルーセルのスパイクをやるための作業ブランチを作り、追加、修正をして動かなくなったときに、意図通り動いていた最新ものにすぐ戻れるように、些細な追加、変更をしただけでも、その修正をコミットしていきます。

このように、確実に動く最もシンプルなものから追加、修正を積み上げていく作業をやっていき、 スパイクとして作っていたSimpleBeach をどこかで Beach に置き換えても良さそうという完成度になったら、開発の本流ブランチへマージすればよいかと思います。

私が、今回のカルーセルなどのような何らかの新たなコンポーネントを利用するときは、上記のように、そのライブラリを試すためのいわばクリーンルームとしての白紙のページを作り、そのライブラリのドキュメントにあるサンプルをコピペして、「確実に動くもの」を出発点にして、業務の要件に応えられるものに徐々に近づけていき、要件を満たすものになりそうかという点を検討しながらカスタマイズしていくという手順を踏むと思います。

以上参考になれば幸いです。

投稿2019/06/10 12:04

編集2019/06/15 12:10
jun68ykt

総合スコア9058

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

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

退会済みユーザー

退会済みユーザー

2019/06/10 15:23

jun68yktさん コメントありがとうございます!あとで直そうと思っていたKeyに関するAlertがご指摘いただいた方法で直りました。Carousel表示はまだ解決していませんが、画像は表示されていないものの、div要素は出てきたのであと少しかもしれません。もう少し調べてみます!
jun68ykt

2019/06/10 23:44

どういたしまして。前進したようで、よかったです???? また行き詰まったら、コメントからお知らせください。
退会済みユーザー

退会済みユーザー

2019/06/12 04:40 編集

jun68yktさん 度々すみません、こちらやっぱり画像が表示できないです。。。 Display:none; が画像に当たってしまっているようなのですが、仕様なのでしょうか? Documentを読み直したり、React-slickを検討してみたり、下記のように{`require({this.props.BHimg})`}など試してみたのですが、画像だけ表示が出ないです。。。(``でくくらずに書いてみたりもしましたがエラーが続くのでやめました) https://teamtreehouse.com/community/react-bootstrap-carousel-images-not-loading (ファイルのパスの問題かと思い、src内の画像とPublic/img内の画像どちらも当ててみましたがうまく行かず。Map()メソッドと相性が良くないのでしょうか?)
jun68ykt

2019/06/14 10:33

私ならこうやって解決していくだろうと思われる手順を、回答のほうに追記2として書きました。
jun68ykt

2019/06/14 10:36

あくまで私ならこういうアプローチで進めますという手順なので、Texonさんの開発状況にそのまま使えるかは分かりませんが、どこか一部でも参考になれば嬉しいです。
退会済みユーザー

退会済みユーザー

2019/06/15 06:34

ありがとうございます!やっぱり1から作り直したほうが良さそうですね・・・ 丁寧な回答ありがとうございます!!がんばります^^
jun68ykt

2019/06/15 11:35

どういたしまして。Goog luck をお祈り申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問