簡體   English   中英

在地圖內有條件地渲染對象的一部分 onClick (REACT.js)

[英]Conditionally render part of object onClick inside a map (REACT.js)

我正在嘗試在單擊按鈕時有條件地呈現對象的一部分(用戶評論)。

正在從 Firebase 數據庫中提取對象。

我有多個對象,並且只想為我單擊的 Result 組件呈現注釋。

用戶評論與所有其他信息(如姓名、日期和評級)存儲在同一對象中。

我最初的方法是為每個 Result 組件設置一個布爾值 false 並嘗試將此值更改為 false 但似乎無法使其正常工作。

下面附上代碼和圖片,任何幫助將不勝感激。

{
accumRating: 3.7
adheranceRating: 4
cleanRating: 2
date: "2020-10-10"
place: "PYGMALIAN"
staffRating: 5
timestamp: t {seconds: 1603315308, nanoseconds: 772000000}
userComment: "Bad"
viewComment: false
}
    const results = props.data.map((item, index) => {
        return (
            <div className='Results' key={index}>
                <span>{item.place}</span>
                <span>{item.date}</span>
                <Rating
                    name={'read-only'}
                    value={item.accumRating}
                    style={{
                        width: 'auto',
                        alignItems: 'center',
                    }}
                />

                <button>i</button>
                {/* <span>{item.userComment}</span> */}

            </div >
        )
    })

界面截圖

在這種情況下,您必須跟蹤每個按鈕切換的單獨狀態。

我想到的解決方案不是最好的,但您可以為按鈕創建一個單擊處理程序並為span添加一個類名,然后檢查該類是否存在。 如果它存在,則隱藏評論。 只需確保按鈕的下一個兄弟是您要隱藏/顯示的目標

const toggleComment = (e) => {
  const sibling =  e.target.nextElementSibling;
  sibling.classList.toggle('is-visible');
  
  if (sibling.classList.contains('is-visible')) {
    sibling.style.display = 'none'; // or set visibility to hidden
  } else {
    sibling.style.display = 'inline-block'; // or set visibility to visible
  }
}
<button onClick={toggleComment}>i</button>
<span>{item.userComment}</span>

你可以這樣試試:

const [backendData, setBackendData] = useState([]);

...

const showCommentsHandler = (viewComment, index) => {
      let clonedBackendData = [...this.state.backendData];
      clonedBackendData[index].viewComment = !viewComment;

      setBackendData(clonedBackendData);

    }

....
return(
   <div>
    ....
    <button onClick={() => showCommentsHandler(item.viewComment, index)}>i</button>
    {item.viewComment && item.userComment}
  <div>

您可以存儲一個包含被點擊的place的數組,例如:

const [ selectedItems, setSelectedItems] = React.useState([]);

const onClick = (el) => {
   if (selectedItems.includes(el.place)) {
     setSelectedItems(selectedItems.filter(e => e.place !== el.place));
   } else {
     setSelectedItems(selectedItems.concat(el));
   }
}

並在您的渲染功能中

const results = props.data.map((item, index) => {
        return (
            <div className='Results' key={index}>
                <span>{item.place}</span>
                <span>{item.date}</span>
                <Rating
                    name={'read-only'}
                    value={item.accumRating}
                    style={{
                        width: 'auto',
                        alignItems: 'center',
                    }}
                />

                <button onClick={() => onClick(item)}>i</button>
{ /* HERE */ }
                { selectedItems.includes(item.place) && <span>{item.userComment}</span> }

            </div >
        )
    })

您需要使用useState否則即使您將屬性從 false 更改為 true,您的組件也不會更新。

為此,您需要一個 id,因為您可能有多個帖子。 (實際上你已經有了一個時間戳,你可以用它來代替 id。)

const [posts, setPosts] = useState([
    {
      id: 1,
      accumRating: 3.7,
      adheranceRating: 4,
      cleanRating: 2,
      date: "2020-10-10",
      place: "PYGMALIAN",
      staffRating: 5,
      timestamp: { seconds: 1603315308, nanoseconds: 772000000 },
      userComment: "Bad",
      viewComment: false
    }
  ]);

創建一個更新單個屬性然后更新狀態的函數。

const handleClick = (id) => {
    const singlePost = posts.findIndex((post) => post.id === id);
    const newPosts = [...posts];
    newPosts[singlePost] = {
      ...newPosts[singlePost],
      viewComment: !newPosts[singlePost].viewComment
    };
    setPosts(newPosts);
  };

然后您可以有條件地呈現評論。

return (
      <div className="Results" key={index}>
        <span>{item.place}</span>
        <span>{item.date}</span>
        <Rating
          name={"read-only"}
          value={item.accumRating}
          style={{
            width: "auto",
            alignItems: "center"
          }}
        />

        <button onClick={() => handleClick(item.id)}>i</button>
        {item.viewComment && <span>{item.userComment}</span>}
      </div>
    );

檢查此 代碼和框以了解其工作原理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM