状态未在反应中更新

时间:2019-02-23 15:05:27

标签: javascript reactjs react-hooks

在给定的代码示例中,sortItemsByEarliest和sortItemsByLatest无法正常运行。对项目进行排序后状态不会更新。

已经在最新和最早的版本中管理了排序正确的输出

const rootElement = document.getElementById("root");
ReactDOM.render( < App / > , rootElement);

function App() {
  const [items, setItems] = React.useState([]);
  const [start, setStart] = React.useState("");
  const [end, setEnd] = React.useState("");
  const [last_inserted_id, setLastInertedId] = React.useState(0);
  return (
    <div>
      <div>{renderControlButton()}</div>
      <div>{renderList()}</div>
    </div>
  );
  function renderControlButton() {
    function sortItemsByEarliest() {
      setItems(items.sort((a, b) => a.id - b.id));
    }
    function sortItemsByLatest() {
      setItems(items.sort((a, b) => b.id - a.id));
    }
    function addToStart() {
      setItems([{ todo: start, id: last_inserted_id + 1 }, ...items]);
      setStart("");
      setLastInertedId(last_inserted_id + 1);
    }
    function addToEnd() {
      setItems([...items, { todo: end, id: last_inserted_id + 1 }]);
      setEnd("");
      setLastInertedId(last_inserted_id + 1);
    }
    return (
      <div>
        <div>
          <input value={start} onChange={e => setStart(e.target.value)} />
          <button onClick={addToStart} type="button">
            Add New Item to Start
          </button>
          <input value={end} onChange={e => setEnd(e.target.value)} />
          <button onClick={addToEnd} type="button">
            Add New Item to End
          </button>
          <button onClick={() => sortItemsByEarliest()} type="button">
            Sort by Earliest
          </button>
          <button onClick={() => sortItemsByLatest()} type="button">
            Sort by Latest
          </button>
        </div>
        <div />
      </div>
    );
  }
  function handleItemChange(value, index) {
    setItems([
      ...items.slice(0, index),
      { id: items[index].id, todo: value },
      ...items.slice(index + 1, items.length)
    ]);
  }
  function renderList() {
    return (
      <div>
        {items.map((item, index) => {
          return (
            <div key={index}>
              <span style={{ width: 200 }}>
                {item.id}.{item.todo}
              </span>
              <input
                onChange={e => {
                  handleItemChange(e.target.value, index);
                }}
                value={item.todo}
              />
            </div>
          );
        })}
      </div>
    );
  }
}
<html>

<head>

  <body>
    <div id='root'></div>
  </body>
  <script src="https://unpkg.com/react@16.8.3/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16.8.3/umd/react-dom.development.js"></script>
</head>

</html>

预期结果是当我单击“按最早排序”按钮时,我要以最早的顺序显示排序的列表,并按最新输入显示“按最新的排序”

1 个答案:

答案 0 :(得分:1)

4.4.3. Installing and Removing Packages,这样您就可以尝试使用相同的数组引用来更新状态。

您可以创建一个包含items的所有元素的新数组,并对其进行排序,它将按预期工作。

function sortItemsByEarliest() {
  setItems([...items].sort((a, b) => a.id - b.id));
}
function sortItemsByLatest() {
  setItems([...items].sort((a, b) => b.id - a.id));
}

function App() {
  const [items, setItems] = React.useState([]);
  const [start, setStart] = React.useState("");
  const [end, setEnd] = React.useState("");
  const [last_inserted_id, setLastInertedId] = React.useState(0);

  function sortItemsByEarliest() {
    setItems([...items].sort((a, b) => a.id - b.id));
  }
  function sortItemsByLatest() {
    setItems([...items].sort((a, b) => b.id - a.id));
  }
  function addToStart() {
    setItems([{ todo: start, id: last_inserted_id + 1 }, ...items]);
    setStart("");
    setLastInertedId(last_inserted_id + 1);
  }
  function addToEnd() {
    setItems([...items, { todo: end, id: last_inserted_id + 1 }]);
    setEnd("");
    setLastInertedId(last_inserted_id + 1);
  }
  function handleItemChange(value, index) {
    setItems([
      ...items.slice(0, index),
      { id: items[index].id, todo: value },
      ...items.slice(index + 1, items.length)
    ]);
  }

  return (
    <div>
      <div>
        <div>
          <div>
            <input value={start} onChange={e => setStart(e.target.value)} />
            <button onClick={addToStart} type="button">
              Add New Item to Start
            </button>
            <input value={end} onChange={e => setEnd(e.target.value)} />
            <button onClick={addToEnd} type="button">
              Add New Item to End
            </button>
            <button onClick={() => sortItemsByEarliest()} type="button">
              Sort by Earliest
            </button>
            <button onClick={() => sortItemsByLatest()} type="button">
              Sort by Latest
            </button>
          </div>
          <div />
        </div>
      </div>
      <div>
        <div>
          {items.map((item, index) => {
            return (
              <div key={index}>
                <span style={{ width: 200 }}>
                  {item.id}.{item.todo}
                </span>
                <input
                  onChange={e => {
                    handleItemChange(e.target.value, index);
                  }}
                  value={item.todo}
                />
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>