调用组件在按钮点击时还是使用多个useState?

huangapple go评论52阅读模式
英文:

Call component on button click or make multiple useStates?

问题

我目前正在尝试使用React和Bootstrap创建图像库。忽略实际内容和语法,以下是代码的大致外观。我想要总共6张图像,它们以3x2的网格方式排列。每个图像都有一个鼠标悬停事件,当鼠标悬停时,它会显示一个带有一些文本的黑色半透明背景。

问题在于它看起来有点混乱。我需要重复使用useState 6次来呈现6个不同的模态弹出窗口。是否有更干净的方法来实现这一点?

我正在考虑的一种方法如下:

<button onClick={() => {
  <ModalPictures          // 这将是一个单独的组件
    props='blah'
    propsTwo='blah'
  />
}}

但是当我尝试这样做时,它实际上不起作用。任何建议将不胜感激。

英文:

I'm currently trying to make an image gallery using react and bootstrap.

ignoring the actual content and syntax, this is kind of what the code looks like. I want a total of 6 images that are side by side in a 3x2 grid. Each image has a onHover where itll show a black transparent background with some text.

function Projects() {
  const [show, setShow] = useState(false);
  const handleClose = () =&gt; setShow(false);
  const handleShow = () =&gt; setShow(true);
  const [show1, setShow1] = useState(false);
  const handleClose1 = () =&gt; setShow1(false);
  const handleShow1 = () =&gt; setShow1(true);
  const [show1, setShow2] = useState(false);
  const handleClose2 = () =&gt; setShow2(false);
  const handleShow2 = () =&gt; setShow2(true);
  x3 more times

  return (
              &lt;div class=&quot;img__wrap&quot;&gt; // this is just the first image
                &lt;img class=&quot;projectCard&quot; src={test} /&gt;
                &lt;div class=&quot;img__description_layer&quot;&gt;
                  &lt;p class=&quot;img__description&quot;&gt;some text.&lt;/p&gt;
                  &lt;button onClick={handleShow}&gt;test&lt;/button&gt;
                  &lt;Modal show={show} onHide={handleClose}&gt;
                    &lt;Modal.Header className=&quot;background&quot; closeButton&gt;
                      &lt;Modal.Title className=&quot;smallerProjectHeadings&quot;&gt;title&lt;/Modal.Title&gt;
                    &lt;/Modal.Header&gt;
                    &lt;Modal.Body className=&quot;background&quot;&gt;
                      &lt;Image className=&#39;projectImg&#39; src={image} alt=&#39;Oneshot&#39; fluid /&gt;
                    &lt;/Modal.Body&gt;
                    &lt;Modal.Footer className=&quot;background&quot; &gt;
                         some stuff here
                    &lt;/Modal.Footer&gt;
                  &lt;/Modal&gt;
                &lt;/div&gt;
              &lt;/div&gt;
  )

The issue is it looks kind of messy. I would have to repeat each of the useStates a total of 6 times to render 6 different modal popups. Is there a cleaner way to do this?

Something I was thinking I'd like to do is like this:

&lt;button onClick={()=&gt;{
 &lt;ModalPictures          // this would a separate component
  props=&#39;blah&#39;
  propsTwo=&#39;blah&#39;
/&gt;
}}

but when I try this, it doesn't actually do anything
any advice would be appreciated.

答案1

得分: 0

只有一个或者最多两个useState已经足够了,可以完成你尝试做的事情。并且,只因为你有6张图片,不意味着你需要使用6个模态框。

我创建了一个简单的沙盒示例来展示如何实现这一点。点击列表项中的任何一个以查看。

调用组件在按钮点击时还是使用多个useState?

const arrayOfLength6 = Array(6)
  .fill()
  .map((_, i) => i);

const Modal = ({ show, data, onHide }) => {
  if (!show) return null;
  return (
    <>
      <p>{data}</p>
      <button onClick={onHide}>Close</button>
    </>
  );
};

export default function App() {
  const [selected, setSelected] = useState();

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <ul>
        {arrayOfLength6.map((i) => (
          <li onClick={() => setSelected(i)} key={i}>
            I'm image at index {i}
          </li>
        ))}
      </ul>

      <Modal
        onHide={() => setSelected(undefined)}
        show={typeof selected !== "undefined"}
        data={selected}
      />
    </div>
  );
}

思路是在点击时将所选图片的信息存储在状态中。在我的示例中,我只存储了图片的索引,但你也可以存储与所选图片相关的数据,并将数据作为props传递给模态框。

英文:

Only one or maybe two useStates are more than enough for what you're trying to do. And just because you have 6 images you don't need to use 6 modals.

I created a simple sandbox to show how this can be achieved. Click on any of the list items to see.

调用组件在按钮点击时还是使用多个useState?

const arrayOfLength6 = Array(6)
  .fill()
  .map((_, i) =&gt; i);

const Modal = ({ show, data, onHide }) =&gt; {
  if (!show) return null;
  return (
    &lt;&gt;
      &lt;p&gt;{data}&lt;/p&gt;
      &lt;button onClick={onHide}&gt;Close&lt;/button&gt;
    &lt;/&gt;
  );
};

export default function App() {
  const [selected, setSelected] = useState();

  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;h1&gt;Hello CodeSandbox&lt;/h1&gt;
      &lt;ul&gt;
        {arrayOfLength6.map((i) =&gt; (
          &lt;li onClick={() =&gt; setSelected(i)} key={i}&gt;
            I&#39;m image at index {i}
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;

      &lt;Modal
        onHide={() =&gt; setSelected(undefined)}
        show={typeof selected !== &quot;undefined&quot;}
        data={selected}
      /&gt;
    &lt;/div&gt;
  );
}

The idea is to keep track of the selected image in the state when it is clicked. In my example, I'm just storing the index of the image but you can store the data associated with an image when it's selected and pass the data as props to the modal.

huangapple
  • 本文由 发表于 2023年4月4日 04:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定