簡體   English   中英

單擊 React 組件時,如何隱藏該組件的所有其他實例?

[英]When a react component is clicked, how do I hide all other instances of that component?

我正在處理我的投資組合,因為我目前是一名失業的初級人員,我發現幾乎不可能讓一個組件的所有實例在該組件的另一個實例的交互(單擊)時消失。

我基本上有用 react-card-flip 創建的卡片; 當用戶點擊其中一張卡片時,它會翻轉並擴大尺寸以顯示更多詳細信息。 這些卡片有多個實例是通過對 axios GET 請求 api.github 創建的...我沒有設法開始工作的部分是使卡片的 rest 在單擊的卡片展開時消失

我讀過在 React 中你不應該使用 querySelector 訪問元素。但即使使用它我仍然無法讓它工作。

我不想完全重構我將在下面添加的代碼:

項目頁面:

const Projects = () => {
  let cards = document.getElementsByClassName("list")
  const [Repos, setRepos] = useState([]);
  const Hider = (id) => {
    console.log(cards)
    // cards.classList.add('hidden')
  }
  useEffect(() => {
    axios.get("https://api.github.com/users/Leehamb99/repos").then((response) => {
      setRepos(response.data)


    })
      .catch(err => {
        console.log(err)
      })

  }, []);

  return (
    <>
      {Repos.map((repo, index) => {
        return (
          <div className="list" onClick={() => { Hider(index) }}>
            <ProjectCard key={index} name={repo.name} />
          </div>
        )
      })}
    </>
  )



};

項目卡組件:

const ProjectCard = (props) => {


  const [flip, setFlip] = useState(false);
  return (
    <ReactCardFlip isFlipped={flip}
      flipDirection="vertical">
      <div style={{
        display: 'flex',
        flexWrap: 'wrap',
        width: '75px',
        height: '75px',
        background: 'gray',
        fontSize: '18px',
        color: 'black',
        margin: '15px',
        borderRadius: '4px',
        textAlign: 'center',
        padding: '20px',
        boxShadow: '10px'
      }} onClick={() => setFlip(!flip)}>
        {props.name}
      </div>
      <div style={{
        width: '500px',
        height: '500px',
        background: '#F0EDE4',
        fontSize: '18px',
        color: 'black',
        margin: '15px',
        borderRadius: '4px',
        textAlign: 'center',
        padding: '20px',
        boxShadow: '10px'
      }} onClick={() => setFlip(!flip)}>
        Computer Science Portal.
      </div>
    </ReactCardFlip>
  );
}

(內聯樣式很快就會移動到 css,不用擔心)所以我的方法是向該組件的所有實例添加一個名為“隱藏”(具有“顯示:無”屬性)的 class 除了我點擊了一個。

由於我的前端知識非常有限,所以我可能會以錯誤的方式進行處理。

如果您正在為您的作品集做這方面的工作,那么遵循良好的代碼標准就更加重要了。

您正在執行的內聯樣式絕對糟糕。 如果看到這樣的代碼,任何半正經的工程師都會扔掉你的簡歷。

將您的樣式放在 css/scss/etc 中。 文件並將其導入到組件中。 或者有一個基本樣式表並在其中完成所有操作。 或者使用樣式化的組件。

或者絕對最低限度,提取樣式變量,以便返回方法可讀。 例如:

const style = { ... }

return <div style={style}/>

但我只對以組件屬性/狀態為條件的稀疏樣式執行此操作。

我的偏好是將每個組件放在自己的文件夾中(在 components 文件夾中),並且在該文件夾中有 index.tsx 和 styles.scss,我們從 index.tsx 導出組件,該組件導入 styles.scss。

對於每個組件。 如果這是有道理的。 但是有很多可接受的方式。

此外,我會考慮切換到 TypeScript - 現在絕大多數商業項目都在他們的項目中使用它。

無論如何,就您遇到的問題而言:

你假設你永遠不想使用查詢選擇器是正確的。 幾乎沒有 99.9% 的時間。

要輕松解決此問題,您可以做的是將邏輯移動到項目而不是 Card 組件中。

就像在項目中一樣:

const [flippedCardIndex, setFlippedCardIndex] = useState(undefined);

然后將 onclick function 傳遞給 Card 組件(調用 setFlippedCardIndex(idx) ),以及另一個道具(例如 isFlipped),根據 flippedCardIndex 是否等於卡中的索引來判斷是否翻轉地圖()。 您可以使用它來確定我們是否要顯示:如果索引不等於 flippedCardIndex,則隱藏。

然后去掉Card中翻轉的state變量。

可能是更好的方法,但這會奏效。

我已經為你簡化了這個。 當點擊卡片時只顯示該卡片而不隱藏其他卡片:

import { ReactElement } from 'react';

import * as React from 'react';

const cards = Array.from({ length: 5 }).map((item, index) => ({
  title: `Item ${index}`,
}));

export default function App(): ReactElement {
  const [showingCard, showCard] = React.useState<number | null>(null);
  function toggleDisplayCard(index) {
    showCard((prev) => (prev === index ? null : index));
  }
  return (
    <div style={{ display: 'flex', gap: '0.5em' }}>
      {showingCard!==null ? (<Card
          isShown={true}
          title={cards[showingCard].title}
          onClick={() => toggleDisplayCard(showingCard)}
        />) : cards.map(({ title }, index: number) => (
        <Card
          title={title}
          onClick={() => toggleDisplayCard(index)}
        />
      ))}
    </div>
  );
}

function Card({
  title,
  onClick,
  isShown
}: {
  isShown?: boolean;
  title: string;
  onClick: any;
}): ReactElement {
  return (
    <div
      style={{
        cursor: 'pointer',
        border: isShown ? '2px solid yellowgreen' : '1px solid silver',
        display: 'flex',
        padding: '1rem',
      }}
      onClick={onClick}
    >
      {title}
    </div>
  );
}

您需要記住以防止在生產中以正確的方式使用 React.memo、React.useMemo、React.useCallback 浪費渲染。

也許這不是最有效的做事方式,因為我在每次點擊卡片時調用迭代,但它似乎有效!

也只用了幾行代碼。 這是我的解決方案:

  const Hider = (id) => {
    click++
    for (let i = 0; i < cards.length; i++) {
      cards[i].classList.add("hidden")
    }
    cards[id].classList.remove("hidden")
    if (click % 2 == 0){
      for (let i = 0; i < cards.length; i++) {
        cards[i].classList.remove("hidden")
      }
    }
  }

暫無
暫無

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

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