css 当一个react组件被单击时,如何隐藏该组件的所有其他示例?

pcww981p  于 2023-01-14  发布在  React
关注(0)|答案(3)|浏览(108)

我正在做我的投资组合,因为我目前是一个失业的大三学生,我发现几乎不可能让一个组件的所有示例在另一个组件示例的交互(点击)后消失。
我基本上有卡片是用React-卡片-翻转创造的;当用户点击其中一张卡片时,它会翻转并扩大尺寸以显示更多细节。这些卡片有多个示例,它们是通过对api. github的axios GET请求创建的......我还没有设法使其工作的部分是使其余的卡片在点击的卡片扩大时消失
我读到过在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中)所以我的方法是添加一个名为“hidden”的类(它有一个“display:none”属性)添加到此组件的所有示例(除了我单击的示例)。
也许我走错了路,因为我的前端知识相当有限。

hs1ihplo

hs1ihplo1#

如果您正在为您的投资组合进行这方面的工作,那么遵循良好的代码标准就显得尤为重要。
你所做的内嵌式是绝对可怕的。任何一个像样的工程师如果看到这样的代码都会扔掉你的简历。
把你的样式放在一个css/scss/etc.文件中,然后导入到组件中。或者有一个基本样式表,然后在那里做所有的事情。或者使用样式化的组件。
或绝对最小值,提取样式变量,以便返回方法可读。例如:

const style = { ... }

return <div style={style}/>

但是我只对稀疏样式进行这种处理,这种样式是以组件属性/状态为条件的。
我的首选是让每个组件都在自己的文件夹中(components文件夹中),并且在该文件夹中有index.tsx和styles.scss,我们在其中从index.tsx导出组件,而该组件导入styles. scss。
对每一个组件。如果有意义的话。但是有很多可以接受的方法。
此外,我会考虑切换到TypeScript -现在绝大多数商业项目都在为他们的项目使用它。
不管怎样,就你的问题而言:
假设您永远不想使用查询选择器是正确的,几乎99.9%的情况下都不想使用。
要很容易地解决这个问题,您可以将逻辑移到Projects中,而不是Card组件中。
就像在项目:
const [翻转卡索引,设置翻转卡索引] =使用状态(未定义);
然后将onclick函数传递给Card组件(它调用setFlippedCardIndex(idx)),沿着另一个属性(例如isFlipped),根据flippedCardIndex是否等于.map()中卡片的索引来决定是否要显示:如果索引不等于flippedCardIndex,则隐藏。
然后去掉Card中翻转的状态变量。
可能是个更好的办法,但那会有用的。

vof42yt1

vof42yt12#

我为你简化了这个过程。当点击一张卡片时,只显示该卡片而不隐藏其他卡片:

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。备忘录,React。使用备忘录,React。使用回调在生产中以正确的方式。

vuv7lop3

vuv7lop33#

也许这不是最有效的方法,因为我在每次点击卡片时都调用一次迭代,但它似乎很有效!
也只用了几行代码。下面是我的解决方案:

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")
      }
    }
  }

相关问题