我有一个初始化状态的父组件,然后在装入后根据获取请求的结果对其进行更新
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))
}, [])
我将状态作为道具传递给子组件。在我的子组件中,我运行检查以查看是否填充了Vehicles数组...如果是,则返回一些jsx,否则不返回任何内容。我的问题是状态更改不会反映在传递的道具中并导致重新渲染。除非刷新页面,否则它将保持为空数组。
我通过
<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请求花了一定的时间才能返回数据(而且我从没有耐心地注意到)...所以我有现在有一个新问题:(
答案 0 :(得分:0)
我不知道prevState
到底是什么,但是我认为您的问题是由传递给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))
}, [])
答案 1 :(得分:0)
为什么要在对象上使用map函数。您的子组件应如下所示:
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>
)
})
)
}
}
答案 2 :(得分:0)
我在CodeSandbox上写了一个工作示例。一些评论:
在组件安装后,您的效果将只运行一次。
如果API成功返回,则会使用前一个创建新的车辆清单。但是prevState
为空,因此在这种情况下与handleVehicles(data)
相同。如果您想在车辆列表中传播数据,请不要忘记handleVehicles(prevState => [...prevState,
...数据 ]);
useEffect(() => {
const token = localStorage.getItem('token')
axios({
//get data from backend
}).then(({data}) => {
handleVehicles(prevState => [...prevState, data])
}).catch((err) => console.log(err))
}, [])
在子组件中,您可能希望映射到车辆列表,而不是第一个元素。因此,您应该删除{p中的[0]
const RenderTableData = (props) => {
if (!props.vehicles[0]) {
return null
} else {
return (
props.vehicles[0].map((vehicle) => {
return (
...
)
})
)
}
}