单击组件时Reactjs动态z索引

ztyzrc3y  于 2022-12-12  发布在  React
关注(0)|答案(3)|浏览(146)

我想完成的是当我点击一个框,前一个框后面的一个是在上面,为了更好的参考请检查下一个代码。
https://codesandbox.io/s/optimistic-payne-4644yf?file=/src/styles.css
所需行为:
1.点击红色框
1.单击蓝色框
并且从底部到顶部的顺序将是:绿色、红色、蓝色
我尝试了很多方法,但我一直搞砸了代码,所以任何帮助都会受到欢迎。

h79rfbju

h79rfbju1#

你是说像这样东西吗?
第一个

xjreopfe

xjreopfe2#

当我输入我的回应时Layhout回答了。那个解决方案是可行的,但我的略有不同,你需要知道zIndex的最大值。

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [data, setData] = useState([
    { id: 1, label: "box 1", class: "box1", index: 0 }, // red
    { id: 2, label: "box 2", class: "box2", index: 1 }, // blue
    { id: 3, label: "box 3", class: "box3", index: 2 } // green
  ]);

  const handlePosition = (index, selectedIndex) =>
    index === selectedIndex ? 2 : index > selectedIndex ? index - 1 : index;

  const handleClick = (selectedIndex) => {
    // nothing happens if we click on the first item
    if (selectedIndex === 2) return;

    setData(
      data.map((i) => ({
        ...i,
        index: handlePosition(i.index, selectedIndex)
      }))
    );
  };

  return (
    <div className="App">
      <div className="box-wrapper">
        {data.map((b) => {
          return (
            <div
              className={b.class}
              key={b.id}
              style={{ zIndex: b.index }}
              onClick={() => handleClick(b.index)}
            >
              {b.label}
            </div>
          );
        })}
      </div>
    </div>
  );
}

下面是CodeSandbox上的完整实现。
最重要的一点是,每个对象的zIndex也是一个UI状态,因此它需要处于useState状态,以便随着用户的点击而改变。在此之后,您需要实现一个算法,以便根据点击的项目对项目进行重新排序。即以下函数:

const handlePosition = (index, selectedIndex) =>
    index === selectedIndex ? 2 : index > selectedIndex ? index - 1 : index;
nxowjjhe

nxowjjhe3#

看起来,期望的结果实际上可能是这样一个解决方案,它独立地处理z-index,而不添加到给定的data,并且如果需要,能够处理3个以上的div项。
下面是一个基本示例,它使用状态数组activeList来处理z-index的更改,因此它独立于data,并且在data扩展时仍然可以工作。
它使用state数组的index来计算每个项的z-index。在单击事件时,它将一个项推到数组的末尾(因此它将具有最高的z索引),作为处理z-index重新排序的轻量级方法。
分叉现场演示:codesandbox

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [activeList, setActiveList] = useState([]);

  const handleClick = (id) =>
    setActiveList((prev) => {
      const current = prev.filter((item) => item !== id);
      return [...current, id];
    });

  const data = [
    { id: 1, label: "box 1", class: "box1" },
    { id: 2, label: "box 2", class: "box2" },
    { id: 3, label: "box 3", class: "box3" }
  ];

  return (
    <div className="App">
      <div className="box-wrapper">
        {data.map((b) => {
          const activeIndex = activeList.findIndex((id) => id === b.id);
          const zIndex = activeIndex >= 0 ? activeIndex + 1 : 0;
          return (
            <div
              className={b.class}
              key={b.id}
              style={{ zIndex }}
              onClick={() => handleClick(b.id)}
            >
              {b.label}
            </div>
          );
        })}
      </div>
    </div>
  );
}

希望这能有所帮助。

相关问题