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

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

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

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

Q&A

解決済

reactjsを使用した一覧表の開閉ボタンを個別に開閉させたい

jud
jud

総合スコア3

React.js

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

1回答

1グッド

0クリップ

418閲覧

投稿2023/03/06 11:18

実現したいこと

以下の設定で、”開く”リンクをクリックすると一覧全ての子の情報が開いてしまいますが、どの様に変更すれば、クリックした親に対する個別の子の情報だけを開く様になるかお教え頂けませんでしょうか?

前提

以下の様なreactjsを使用した記述で顧客関連情報を表示する一覧があります。以下のlevel1とlevel2は親子関係にあり”開く”リンクをクリックするとその子である情報が表示される設定にしたいと考えております。

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

以下の設定で、”開く”リンクをクリックすると一覧全ての子の情報が開いてしまいます。

該当のソースコード

import axios from "axios" import { useEffect, useState } from "react"; import './css/List.css'; export default function List() { const [users, setUsers] = useState([]); useEffect(() => { getUsers(); }, []); function getUsers() { axios.get('https://xxxxxx/api/users/').then(function(response) { console.log(response.data); setUsers(response.data); }); } const [isOpen, setIsOpen] = useState(true); return ( <div className="List"> {Object.values(users).map((user, key) => <div className="level1"> {user.level == 1 && <p>{user.name}</p> } <font onClick={() => setIsOpen(!isOpen)}> {isOpen ? "開く" : "閉じる"} </font> </div> {user.level == 2 && !isOpen && <p>{user.address}</p> <p>{user.email}</p> <p>{user.profession}</p> } )} </div> ) }

試したこと

loop内のonClick処理から値を渡そうと試しました。

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

axios@1.3.1
react-dom@18.2.0
react-scripts@5.0.1
react@18.2.0

uky🎉を押しています

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

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

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

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

hoshi-takanori

2023/03/06 16:24

isOpen を配列か何かにするとか…。
uky

2023/03/07 01:33 編集

user.levelってどのような値で、どう変化するのでしょうか? どのような値 → 1or2 の数値? 配列? どう変化する → isOpenと同じような動き?? → 開くと数字が2に変わるとか できればuserのオブジェクトを見せていただきたいです。よろしくお願いします。
jud

2023/03/07 02:07

説明不足で申し訳ございません。dbのテーブル内で親であればlevelは1、子であれば2です。levelは1か2だけです。数値であり変化は致しません。
uky

2023/03/07 02:29

ということは、「レベル1のname(font)をクリックしたら、レベル2のデータを表示する」ということを実現したい、という認識であっていますか?
jud

2023/03/07 02:48

uky様、 混乱させてしまい大変恐縮でございます。開くというリンクがlevel1の下に配置されてあり、クリックするとlevel2のデータを表示させたいです。ただ上記の顧客情報の(name,address,email,proffession)というDB構造は混乱させていますので、忘れて頂き(申し訳ございません。)、通常の親子関係にある、(コメント、返信)などの関係の複数の親がある中でその個別の子のデータを表示するという設定を想定して頂きたく存じます。

回答1

2

ベストアンサー

あまり綺麗ではないですが。。。

問題

  • isOpen setIsOpenがユーザーのレコードごとに存在していないこと
    • Listコンポーネント内にisOpen setIsOpen が一つしか存在していないため、あるユーザーをクリックすると全てのユーザーの情報が表示されてしまっていた

修正方針

  • 選択している一意のユーザーデータをstate管理し、比較をすることで対象のレコードのみを表示させる
    • 一意のユーザーデータがなければ動かないです。。。
  • levelによる表示の区別は不要と思いましたので削除しました

修正後のコード

js

1// 表示用の関数から除外しました 2function getUsers() { 3 axios.get('https://xxxxxx/api/users/').then(function(response) { 4 console.log(response.data); 5 setUsers(response.data); 6 }); 7} 8 9export default function List() { 10 // このコンポーネント内で管理されるstateを上位の方にまとめておくと読みやすくなります 11 const [users, setUsers] = useState([]); 12 const [selectedName, setSelectedName] = useState('') // 一意に定まるデータがあるのであれば、それをstateとして管理する。(ここではnameを代用します) 13 // その次にアクション 14 useEffect(() => { 15 getUsers(); 16 }, []); 17 // onClickのアクションをuser.nameが一致しているかどうかで分ける 18 const onClick = (name) => { 19 selectedName === name ? setSelectedName("") : setSelectedName(name); 20 }; 21 22 return ( 23 <div className="List"> 24 {Object.values(users).map((user, key) => 25 <div className="level1"> 26 <p>{user.name}</p> 27 <font onClick={() => onClick(user.name)}> {selectedName === user.name ? "閉じる" : "開く"} </font> 28 </div> 29 {selectedName === user.name && ( 30 <p>{user.address}</p> 31 <p>{user.email}</p> 32 <p>{user.profession}</p> 33 )} 34 )} 35 </div> 36 ) 37}

投稿2023/03/07 03:05

編集2023/03/07 04:21
uky

総合スコア136

jud😄を押しています
jud👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

jud

2023/03/07 05:18

uky様、 回答頂きまして感謝致します。あれこれと確認をしておりました。個別の子を表示しております。しかしながら、例えば、user.nameが同じ場合、同じ名前の複数の子を開いてしまいます。名前が同じということからでしょうか?なので、user.idで試しましたが、(頂いた記述のnameをidに変更して)今度は全く表示しなくなりました。何かお分かりになりますでしょうか?
jud

2023/03/07 05:35

uky様、 個別の子だけが表示されました。本当に説明不足で大変恐縮でございましたが、感謝の限りでございます。idを使用し、子のセクションでselectedName === user.parent_idという設定にすることで期待通りに動作しております。ありがとうございます。
uky

2023/03/07 06:16

意図通りの挙動となってよかったです! `name`でなく`id`を使用するのであれば、変数名も`selectedUserId`などに変更した方が可読性の面で優れると思います。ご参考までに。
jud

2023/03/07 06:52

uky様、 それではselectedUserIdに変更いたします。ありがとうございます。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.83%

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

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

質問する

関連した質問

同じタグがついた質問を見る

React.js

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