状态未在反应中更新
state is not updated in react
在给定的代码示例中,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>
预期结果是当我单击 "Sort by Earliest" 按钮时我想按最早的顺序显示排序列表,并按最新的输入显示 "Sort by Latest"
sort
sorts the array in place 这将成功,因此您尝试使用相同的数组引用更新状态。
您可以创建一个包含 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>
在给定的代码示例中,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>
预期结果是当我单击 "Sort by Earliest" 按钮时我想按最早的顺序显示排序列表,并按最新的输入显示 "Sort by Latest"
sort
sorts the array in place 这将成功,因此您尝试使用相同的数组引用更新状态。
您可以创建一个包含 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>