题目:实现antd穿梭框的基本功能

antd的穿梭框实现有以下几个要点:

  1. 数据分为两部分,source-左侧,target-右侧
  2. 选项在左右两个框中穿梭,实际上是对 source 和 target 这两个数组进行增删的数据维护

下面是完整实现,线上demo

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

export default function Transfer(props) {
  const [source, setSource] = useState(props.dataSource);
  const [target, setTarget] = useState([]);
  const [sourceSelectedKeys, setSourceSelectedKeys] = useState([]);
  const [targetSelectedKeys, setTargetSelectedKeys] = useState([]);

  const onSelectChange = (key, type, e) => {
    if (type === "source") {
      setSourceSelectedKeys([...sourceSelectedKeys, key]);
    } else {
      setTargetSelectedKeys([...targetSelectedKeys, key]);
    }
  };

  const moveToRight = () => {
    const dataSourceCpy = [...source];
    const moveItem = dataSourceCpy.filter((item) =>
      sourceSelectedKeys.includes(item.key)
    );
    const newSource = dataSourceCpy.filter(
      (item) => !sourceSelectedKeys.includes(item.key)
    );
    setTarget([...moveItem, ...target]);
    setSource(newSource);
    setSourceSelectedKeys([]);
  };

  const moveToLeft = () => {
    const targetCpy = [...target];
    const moveItem = targetCpy.filter((item) =>
      targetSelectedKeys.includes(item.key)
    );
    const newTarget = targetCpy.filter(
      (item) => !targetSelectedKeys.includes(item.key)
    );
    setTarget(newTarget);
    setSource([...moveItem, ...source]);
    setTargetSelectedKeys([]);
  };

  const handleTransfer = (type) => {
    if (type === "right") {
      moveToRight();
    } else {
      moveToLeft();
    }
  };

  return (
    <div className="container">
      <div className="dataSource">
        {source.map((item) => {
          return (
            <div key={item.key}>
              <input
                type="checkbox"
                name={item.title}
                onChange={(e) => {
                  onSelectChange(item.key, "source", e);
                }}
              />
              <label htmlFor={item.title}>{item.title}</label>
            </div>
          );
        })}
      </div>
      <div className="operation">
        <button
          onClick={() => {
            handleTransfer("right");
          }}
        >
          {">"}
        </button>
        <button
          onClick={() => {
            handleTransfer("left");
          }}
        >
          {"<"}
        </button>
      </div>
      <div className="target">
        {target.map((item) => {
          return (
            <div key={item.key}>
              <input
                type="checkbox"
                name={item.title}
                onChange={(e) => {
                  onSelectChange(item.key, "target", e);
                }}
              />
              <label htmlFor={item.title}>{item.title}</label>
            </div>
          );
        })}
      </div>
    </div>
  );
}
.container {
  display: flex;
}

.dataSource {
  border: 1px solid black;
  width: 200px;
  height: 300px;
}

.operation {
  display: flex;
  flex-direction: column;
}

.target {
  border: 1px solid black;
  width: 200px;
  height: 300px;
}

Leon
1.4k 声望1k 粉丝