состояние не обновляется в реакции - PullRequest
0 голосов
/ 23 февраля 2019

В приведенном примере кода 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 голосов
/ 23 февраля 2019

sort сортирует массив на месте , что сделает его таким образом, что вы пытаетесь обновить состояние с той же ссылкой на массив.

Вы можете создать новый массив со всеми элементами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>
...