![](/img/trans.png)
[英]If the props for a child component are unchanged, does React still re-render it?
[英]React - Passing state as props not causing re-render on child component
我有一個啟動 state 的父組件,然后在安裝后根據獲取請求的結果更新它
const [vehicles, handleVehicles] = useState([])
useEffect(() => {
const token = localStorage.getItem('token')
axios({
//get data from backend
}).then(({data}) => {
handleVehicles(prevState => [...prevState, data])
}).catch((err) => console.log(err))
}, [])
我將 state 作為道具傳遞到子組件中。 在我的子組件中,我運行檢查以查看車輛數組是否已填充...如果是,我返回一些 jsx,否則我什么也不返回。 我的問題是 state 更改不會反映在傳遞的道具中並導致重新渲染。 除非我刷新頁面,否則它會保留在一個空數組中。
我通過
<RenderTableData vehicles={vehicles} />
我的子組件是:
const RenderTableData = (props) => {
if (!props.vehicles[0]) {
return null
} else {
return (
props.vehicles[0].map((vehicle) => {
return (
<tr key={vehicle._id}>
<td>{vehicle.name}</td>
<td>{vehicle._id}</td>
<td><button className="has-background-warning">Edit</button></td>
<td><button className="has-background-danger">Remove</button></td>
</tr>
)
})
)
}
}
我將如何解決這個問題?
編輯- 它實際上是按原樣工作的......由於某種原因,http 請求需要一段時間才能返回數據(而且我從來沒有足夠的耐心注意到)......所以我現在有一個新問題:(
我不知道prevState
到底是什么,但我認為您的問題是由將 function 而不是新值傳遞給handleVehicles
引起的。 所以你的代碼應該是:
const [vehicles, handleVehicles] = useState([])
useEffect(() => {
const token = localStorage.getItem('token')
axios({
//get data from backend
}).then(({data}) => {
handleVehicles([...prevState, data])
}).catch((err) => console.log(err))
}, [])
為什么您在 object 上使用 map function。 您的子組件應如下所示:
const RenderTableData = (props) => {
if (!props.vehicles[0]) {
return null
} else {
return (
props.vehicles.map((vehicle) => {
return (
<tr key={vehicle._id}>
<td>{vehicle.name}</td>
<td>{vehicle._id}</td>
<td><button className="has-background-warning">Edit</button></td>
<td><button className="has-background-danger">Remove</button></td>
</tr>
)
})
)
}
}
我在CodeSandbox寫了一個工作示例。 一些評論:
在組件安裝后,您的效果將只運行一次。 如果 API 返回成功,則會使用之前的列表創建新的車輛列表。 但是prevState
是空的,所以在這種情況下,這與handleVehicles(data)
相同。 如果您想在車輛列表中傳播數據,請不要忘記handleVehicles(prevState => [...prevState,
...data ]);
useEffect(() => {
const token = localStorage.getItem('token')
axios({
//get data from backend
}).then(({data}) => {
handleVehicles(prevState => [...prevState, data])
}).catch((err) => console.log(err))
}, [])
在您的子組件中,您可能希望 map 超過車輛列表,而不是第一個元素。 所以,你應該刪除[0]
在
const RenderTableData = (props) => {
if (!props.vehicles[0]) {
return null
} else {
return (
props.vehicles[0].map((vehicle) => {
return (
...
)
})
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.