首页 > 解决方案 > 带有 React Hooks 的动态状态

问题描述

我正在尝试使用该map()函数呈现一个数组,同时使用一些已建立的状态为每个元素提供其自己的唯一类名(基于索引值)。使用钩子单击时,元素应更改颜色。我遇到了一个问题,className = {"header" + {index}.index}它给出了正确的状态名称(header0、header1 等)但对应于一个字符串而不是用相同名称建立的类名。

const data = ["James", "John", "Jessica", "Jamie"];

export default function App() {
  const [header0, setHeader0] = useState("visable");
  const [header1, setHeader1] = useState("visable");
  const [header2, setHeader2] = useState("visable");
  const [header3, setHeader3] = useState("visable");

  const clicked = (index) => {
    if (index === 0) {
      setHeader0("invisible");
    } else if (index === 1) {
      setHeader1("invisible");
    }
    /*Is there an alternative like {setHeader + index} instead of this loop?*/
  };

  return (
    <div className="App">
      <h1>Sample Project</h1>
      {data.map((value, index) => (
        <h1
          className={"header" + { index }.index}
          onClick={() => {
            clicked(index);
          }}
        >
          {/* classname should be the state "header0" but right now its just a string */}
          Hello {value}!
        </h1>
      ))}
    </div>
  );
}

这是我正在尝试的代码沙箱,其中有一些出现问题的评论。我是否以正确的方式解决这个问题? https://codesandbox.io/s/wispy-star-38qvw?fontsize=14&hidenavigation=1&theme=dark

编辑 wispy-star-38qvw

任何帮助是极大的赞赏!

标签: javascriptreactjsreact-hooks

解决方案


您可以使用单个状态数组来获得可见性。

此外,如果您将索引存储在单击元素的 HTML 数据集 ( data-index) 中,则不需要为每个索引使用单独的闭包/函数。

const data = ["James", "John", "Jessica", "Jamie"];

function App() {
  const [visibilities, setVisibilities] = React.useState(() => data.map((x) => true));

  const handleClick = (event) => {
    const index = parseInt(event.currentTarget.dataset.index, 10);
    const newVisibilities = [...visibilities];
    newVisibilities[index] = !newVisibilities[index];
    setVisibilities(newVisibilities);
  };

  return (
    <div className="App">
      {data.map((value, index) => (
        <h1 data-index={index} onClick={handleClick} className={visibilities[index] ? "selected" : undefined}>
          Hello {value}, you are {visibilities[index] ? "visible" : "hidden"}!
        </h1>
      ))}
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector("main"));
.selected {
  background: lightgreen;
}

h1 {
  cursor: pointer;
  user-select: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<main></main>


推荐阅读