我有以下状态:
const [places, setPlaces] = useState(false)
const [selectedPlaces, setSelectedPlaces] = useState([])
我通过调用一个 API 异步填充地点,该 API 返回一个类似于以下内容的对象数组:
[
{name: "Shop #1", id: 1},
{name: "Shop #2", id: 2}
]
我的目标是渲染这些对象,并在 selectedPlaces 状态中添加/删除它们的 ID。
渲染:
return (
<div>
<div>
You have selected {selectedPlaces.length} total places
</div>
(places === false)
? <div>Loading...</div>
: places.map(place => { // render places from the places state when loaded
let [name, id] = [place.name, place.id]
return <div onClick={() => {
setSelectedPlaces(selected => {
selected.push("dummy data to simplify")
return selected
})
}}>{name}</div>
})
</div>
)
我已经移除了钥匙并添加了虚拟数据以使动作更简单。
<块引用>单击 div 时出现问题,直到我使用快速刷新或通过其他方法(使用浏览器/NextJS)强制重新渲染之前,“您已选择...总位置”不会刷新.这是正确的行为吗?好像状态没有改变,但 console.log
上的 setSelectedPlaces
显示新数据,表示它正在改变。
我试过了:
答案 0 :(得分:2)
为三元运算符添加一个 {}
包装器:
{
places === false
? (...)
: (....)
}
push
改变状态。在 concat
setSelectedPlaces
setSelectedPlaces(selected =>
selected.concat("abc")
)
let [name, id] = [place.name, place.id]
可以更改为 let { name, id } = place
这是一个片段:
const { useState } = React;
function App() {
const [places, setPlaces] = useState([
{ name: "Shop #1", id: 1 },
{ name: "Shop #2", id: 2 }
])
const [selectedPlaces, setSelectedPlaces] = useState([])
const onPlaceClick = id => setSelectedPlaces(state => state.concat(id))
return (
<div>
<div> You have selected {selectedPlaces.length} total places </div>
{ (places === false)
? <div>Loading...</div>
: places.map(({ id, name }) =>
<div onClick={_ => onPlaceClick(id)}>{name}</div>
)
}
<span>{selectedPlaces.join()}</span>
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>