如何对其中随机生成的数字的卡片列表进行排序?

How can I sort a list of cards with randomly generated numbers inside of them?

我在按下按钮时生成卡片。这些卡片有一个随机生成的数字,介于 0 和 100 之间。我正在尝试设置一个组件或函数,当我单击排序按钮时,它允许我按数字顺序升序或降序或两者对所有这些卡片进行排序。我尝试了以下代码。请记住,这些都包含在同一个 App 组件中。

随机数在添加卡片组件中生成。

我觉得我超级接近,但我不知道我错过了什么。


  const sortTypes = {
    up: {
      class: "sort-up",
      fn: (a, b) => a.number - b.number,
    },

    down: {
      class: "sort-down",
      fn: (a, b) => b.number - a.number,
    },

    default: {
      class: "sort",
      fn: (a, b) => a,
    },
  };

  const sortAll = () => {
    state = {
      currentSort: 'default'
    };

    onSortChange = () => {
      const { currentSort } = this.state;
      let nextSort;

      if (currentSort === 'down') nextSort = 'up';
      else if (currentSort === 'up') nextSort = 'default';
      else if (currentSort === 'default') nextSort = 'down';

      this.setState({
        currentSort: nextSort
      });
    };

    };
  

  return (
    <body>
      <header>
        <div className="ui buttons">
          <button type="button" onClick={addCard} className="ui button mb-1 mt-1 mr-1"><i className="plus icon"></i>Add Card</button>
          <div className="or mb-1 mt-1"></div>
          <button type="button" onClick={sortAll} className="ui positive button mb-1 mt-1 mr-1"><i className="redo icon"></i>Sort All</button>
        </div>
      </header>

问题

  1. 功能组件是“无实例”的,因此没有定义的 this 可供参考。
  2. onSortChange 是要用于更新当前排序的按钮 onClick 处理程序。

解决方案

  1. currentSort 移动到 useState 挂钩中的组件状态。

    const [currentSort, setCurrentSort] = useState("default");
    
  2. 修复 onSortChange 处理程序以正确更新状态。

    const onSortChange = () => {
      let nextSort;
    
      if (currentSort === "down") nextSort = "up";
      else if (currentSort === "up") nextSort = "default";
      else if (currentSort === "default") nextSort = "down";
    
      setCurrentSort(nextSort);
    };
    
  3. 在渲染器中使用内联“排序”return。请记住 array.prototype.sort 是就地排序,即它会改变数组。要避免意外改变状态,请先复制数组。

    {cards
      .slice() // <-- copy
      .sort(sortTypes[currentSort].fn) // <-- select sort function
      .map((cardNumber, index) => (
        <MainCard
          number={cardNumber.number}
          key={cardNumber.id}
          onRemove={() => removeCard(cardNumber.id)}
        />
      ))}
    
  4. 将正确的处理程序附加到按钮

    <button
      type="button"
      onClick={onSortChange}
      className="ui positive button mb-1 mt-1 mr-1"
    >
      <i className="redo icon"></i>Sort All
    </button>
    

演示

完整代码:

const generateId = (seed = 0) => () => seed++;

const getRandomNumber = function (min, max) {
  let getRandom = Math.floor(Math.random() * max + min);
  return getRandom;
};

const sortTypes = {
  up: {
    class: "sort-up",
    fn: (a, b) => a.number - b.number
  },

  down: {
    class: "sort-down",
    fn: (a, b) => b.number - a.number
  },

  default: {
    class: "sort",
    fn: (a, b) => a
  }
};

const MainCard = ({ number, onRemove }) => {
  return (
    <div className="card">
      <button
        onClick={onRemove}
        className="ui mini red basic icon button"
        style={{
          position: "absolute",
          top: "0",
          right: "0"
        }}
      >
        X
      </button>
      {number}
    </div>
  );
};

export default function App() {
  const [cards, setCards] = useState([]);
  const [currentSort, setCurrentSort] = useState("default");

  const addCard = () => {
    setCards((cards) => [
      ...cards,
      {
        id: generateId(),
        number: getRandomNumber(0, 101)
      }
    ]);
  };

  const removeCard = (id) => {
    setCards((cards) => cards.filter((el) => el.id !== id));
  };

  const onSortChange = () => {
    let nextSort;

    if (currentSort === "down") nextSort = "up";
    else if (currentSort === "up") nextSort = "default";
    else if (currentSort === "default") nextSort = "down";

    setCurrentSort(nextSort);
  };

  return (
    <body>
      <header>
        <div className="ui buttons">
          <button
            type="button"
            onClick={addCard}
            className="ui button mb-1 mt-1 mr-1"
          >
            <i className="plus icon"></i>Add Card
          </button>
          <div className="or mb-1 mt-1"></div>
          <button
            type="button"
            onClick={onSortChange}
            className="ui positive button mb-1 mt-1 mr-1"
          >
            <i className="redo icon"></i>Sort All
          </button>
        </div>
      </header>

      <div className="card-container">
        {cards
          .slice()
          .sort(sortTypes[currentSort].fn)
          .map((cardNumber) => (
            <MainCard
              number={cardNumber.number}
              key={cardNumber.id}
              onRemove={() => removeCard(cardNumber.id)}
            />
          ))}
      </div>

      <aside className="showHide"></aside>

      <footer>
        <h3 className="text-center text-muted">Footer</h3>
      </footer>
    </body>
  );
}