简体   繁体   English

React 中基于 Material UI 中 IconButton 组件的 onClick 属性的条件渲染

[英]Conditional rendering in React based on the onClick property of the IconButton component in Material UI

import "./styles.css";
import React, { useState } from "react";
import { IconButton } from "@material-ui/core";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

export default function App() {
  const [expand, setExpand] = useState({
    arrowA: false,
    arrowB: false,
    arrowC: false,
    arrowD: false
  });

  const handleChange = (e) => {
    setExpand({
      ...expand,
      [e.currentTarget.name]: !expand.arrowA,
      [e.currentTarget.name]: !expand.arrowB,
      [e.currentTarget.name]: !expand.arrowC,
      [e.currentTarget.name]: !expand.arrowD
    });
  };

  return (
    <div className="App">
      <h1>React conditional rendering</h1>
      <h2>
        The component below should render if the user clicks on the arrow, and
        be removed if the user clicks the arrow again.
      </h2>

      <h5>
        This arrow should show the first part of the text.{" "}
        <IconButton
          variant="contained"
          size="small"
          color="primary"
          aria-label="expand"
          name="arrowA"
          onClick={handleChange}
        >
          {<ExpandMoreIcon />}
        </IconButton>
      </h5>

      <h5>
        This arrow show the second part of the text if clicked, and be possible
        to remove.
        <IconButton
          variant="contained"
          size="small"
          color="primary"
          aria-label="expand"
          name="arrowB"
          onClick={handleChange}
        >
          {<ExpandMoreIcon />}
        </IconButton>
      </h5>

      <h5>
        This arrow should show the third part of the text below.{" "}
        <IconButton
          variant="contained"
          size="small"
          color="primary"
          aria-label="expand"
          name="arrowC"
          onClick={handleChange}
        >
          {<ExpandMoreIcon />}
        </IconButton>
      </h5>

      <h5>
        This was really the last part.{" "}
        <IconButton
          variant="contained"
          size="small"
          color="primary"
          aria-label="expand"
          name="arrowD"
          onClick={handleChange}
        >
          {<ExpandMoreIcon />}
        </IconButton>
      </h5>
      {expand.arrowA ? (
        <h2>
          This is the first start of the story, let's see if we can add the
          rest.
        </h2>
      ) : null}

      {expand.arrowB ? (
        <h2>This is the middle part, it starts to break soon.</h2>
      ) : null}
      {expand.arrowC ? (
        <h2>
          We are nearing the end. But as you see, this state management is not
          optimal.
        </h2>
      ) : null}

      {expand.arrowD ? (
        <h2>
          This is was all I wanted to show. But why is removing this so hard?
          How to make this better?
        </h2>
      ) : null}
    </div>
  );
}

first of all, thanks for being here.首先,感谢您来到这里。 I am a beginner in React and have a question regarding how to make my state management more optimal and better working.我是 React 的初学者,并且有一个关于如何使我的 state 管理更优化和更好工作的问题。

I am trying to render multiple components in one React hook, to avoid having to create many different hooks.我试图在一个 React 钩子中渲染多个组件,以避免创建许多不同的钩子。 But my solution isn't working properly and not very optimal.但是我的解决方案不能正常工作,也不是很理想。 I lack knowledge how to make the state more dynamic, but I feel I am close.我缺乏如何让 state 更有活力的知识,但我觉得我很接近。 Here is the example in: Code Sandbox以下是示例:代码沙箱

If you open the Code Sandbox, in the second attempt file, I am trying to set [e.currentTarget.value]: [e.currentTarget.status] to try to get the status from the IconButton, which I there store as status={.expand.checkedA} .如果您打开代码沙箱,在第二次尝试文件中,我尝试设置[e.currentTarget.value]: [e.currentTarget.status]以尝试从 IconButton 获取状态,我将其存储为status={.expand.checkedA} But that isn't how React state management works apparently.但这显然不是 React state 管理的工作方式。

Could someone enlighten me on what's best practice here?有人可以告诉我这里的最佳做法是什么吗? If you have a recommendation for an alternative way to conditionally render multiple components, I'd also be curious.如果您对有条件地渲染多个组件的替代方法有建议,我也会很好奇。

Cheers.干杯。

I think you're doing fine I would just change a few things to make it work:我认为您做得很好,我只需更改一些内容即可使其正常工作:

First make the handleChange do this instead of the current code:首先让handleChange执行此操作,而不是当前代码:

const handleChange = (e) => {
  setExpand({
   ...expand,
   [e.currentTarget.name]: !expand[e.currentTarget.name]
  });
};

In this way you will only change the one you're clicking and the rest will stay the same.这样,您只需更改您单击的那个,rest 将保持不变。

Secondly you don't need the ternary operator in your jsx, you can use the && operator:其次,您的 jsx 中不需要三元运算符,您可以使用 && 运算符:

  {expand.arrowA && (
    <h2>
      This is the first start of the story, let's see if we can add the
      rest.
    </h2>
  )}

Check the forked sandbox if you have questions: https://codesandbox.io/s/cool-fog-h7vct?file=/src/App.js:2073-2226如果您有任何问题,请检查分叉沙箱: https://codesandbox.io/s/cool-fog-h7vct?file=/src/App.js:2073-2226

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM