简体   繁体   中英

state is not updated in react

In the given code sample sortItemsByEarliest and sortItemsByLatest does not work as I wish. state is not updated after sorting the items.

Already consoled the output of sorting it's correct in both latest and earliest

 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>

expected result is when i click "Sort by Earliest" button I want to display sorted list in the order Earliest and with "Sort by Latest" by latest inputs

sort sorts the array in place which will make it so you try to update the state with the same array reference.

You can create a new array with all the elements of items in it and sort that and it will work as expected.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM