使用 react useState 移动列表元素不起作用

moving list elements using react useState not working

我有以下代码:

import React, { useState } from "react";

export default function App() {
  const [arr, setArr] = useState([
    { id: 1, name: "orange" },
    { id: 2, name: "lemon" },
    { id: 3, name: "strawberry" },
    { id: 4, name: "apple" }
  ]);

  const onMoveUp = function (key) {
    if (key === 0) return;
    const items = arr;
    const index = key - 1;
    const itemAbove = items[index];
    items[key - 1] = items[key];
    items[key] = itemAbove;
    console.log(items);
    setArr(items);
  };

  const onMoveDown = function (key) {
    const items = arr;
    if (key === items.length - 1) return;
    const index = key + 1;
    const itemBelow = items[index];
    items[key + 1] = items[key];
    items[key] = itemBelow;
    setArr(items);
  };

  return (
    <div>
      <ul>
        {arr.map((item, key) => (
          <li key={key}>
            <div>
              {item.id} - {item.name}
            </div>
            <div>
              <span onClick={() => onMoveUp(key)}>&#x25B2;</span>
              <span onClick={() => onMoveDown(key)}>&#x25BC;</span>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

它应该做的是使用箭头上下移动列表元素。我尝试了很多方法,但似乎没有任何效果。我目前正在探索 useEffect。该数组确实发生了变化,但未反映在 UI 中。请帮忙。

不建议直接更改状态值。最好复制一份你的状态
好好学习

这里有一个 spread operator 的例子:

import React, { useState } from "react";

export default function App() {
  const [arr, setArr] = useState([
    { id: 1, name: "orange" },
    { id: 2, name: "lemon" },
    { id: 3, name: "strawberry" },
    { id: 4, name: "apple" }
  ]);

  const onMoveUp = function (key) {
    if (key === 0) return;
    const items = [...arr];
    const index = key - 1;
    const itemAbove = items[index];
    items[key - 1] = items[key];
    items[key] = itemAbove;
    console.log(items);
    setArr(items);
  };

  const onMoveDown = function (key) {
    const items = [...arr];
    if (key === items.length - 1) return;
    const index = key + 1;
    const itemBelow = items[index];
    items[key + 1] = items[key];
    items[key] = itemBelow;
    setArr(items);
  };

  return (
    <div>
      <ul>
        {arr.map((item, key) => (
          <li key={key}>
            <div>
              {item.id} - {item.name}
            </div>
            <div>
              <span onClick={() => onMoveUp(key)}>&#x25B2;</span>
              <span onClick={() => onMoveDown(key)}>&#x25BC;</span>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

在 React 中,UI 必须更改为状态中的新对象才能更新。像 React 这样的框架使用不变性进行状态管理。

例如,在您的函数 onMoveUp 中,items 与使用 useState 生成的 arr 是同一个数组。 React 不会更新 UI 因为你改变了同一个对象并将这个值存储在状态中。

通过修改代码如下保存状态中的新对象:

const onMoveUp = function (key) {
  if (key === 0) return;
  const items = [...arr]; // Create a new object with Copy Object
  const index = key - 1;
  const itemAbove = items[index];
  items[key - 1] = items[key];
  items[key] = itemAbove;
  console.log(items);
  setArr(items);
};