React从子组件重新渲染父组件不起作用



我有一个父组件(DevicePage(,它加载子组件(Device(的倍数。在子组件中,我有用于签入和签出设备的按钮。当我点击DevicePage上的按钮时,页面不会重新呈现,按钮状态也不会改变。

我尝试了一些建议的答案,将一个函数传递给子级,子级可以调用该函数来更新父级的状态(请参阅此处"如何从子级组件重新呈现父级组件"(,但在我的情况下不起作用,也不确定原因。

这是我的:

const [devices, setDevices] = useState();
const [count, setCount] = useState(0);
useEffect(() => {
setCount(1)
DeviceService.getAll()
.then(res => {
if(res.data.length > 0) {
setDevices(res.data);
}
});
}, [])
function checkoutDevice(id) {
console.log("About to checkout device");
DeviceService.checkoutDevice(id)
.then(res => {
console.log("Device checked out")
})
.catch(err => "Error checking out device: " + err);
}
function checkinDevice(id) {
DeviceService.checkinDevice(id)
.then(res => {
console.log("Device checked in")
})
.catch(err => "Error checking out device: " + err);
}
function devicesList() {
if(devices) {
return devices.map(currDevice => {
return <Device device={currDevice} checkoutDevice={checkoutDevice} checkinDevice={checkinDevice} key={currDevice._id} />;
});
}
}
return (
<div>
<table className="table">
<thead className="thead-light">
<tr>
<td>Tag</td>
<td>Category</td>
<td>Make</td>
<td>Model</td>
</tr>
</thead>
<tbody>
{devicesList()}
</tbody>
</table>
</div>
)
}

儿童

return (
<tr>
<td><Link to={"/devices/" + props.device._id}>{props.device.tag}</Link></td>
<td>{props.device.category}</td>
<td>{props.device.make}</td>
<td>{props.device.modelName}</td>
{
props.device.available?
<>
<td>
<button type="button" className="btn btn-primary" onClick={() => {props.checkoutDevice(props.device._id)}}>Checkout</button>
</td>
</>
:
<>
<td>
<button type="button" className="btn btn-primary" onClick={() => {props.checkinDevice(props.device._id)}}>Checkin</button>
</td>
</>
}
{
currUser.isAdmin?
<>
<td>
<Link to={{pathname: "/devices/edit/" + props.device._id, 
state: {
tag: props.device.tag
}}}>
edit
</Link>
</td>
</>
: 
null
}
</tr>
)

您的问题是"页面不会重新呈现,按钮状态也不会更改&";,我的假设是当你点击";结账";按钮,您希望它更改为";签入";按钮,反之亦然。查看设备组件中的此代码块:

{
props.device.available?
<>
<td>
<button type="button" className="btn btn-primary" onClick={() => {props.checkoutDevice(props.device._id)}}>Checkout</button>
</td>
</>
:
<>
<td>
<button type="button" className="btn btn-primary" onClick={() => {props.checkinDevice(props.device._id)}}>Checkin</button>
</td>
</>
}

有了这个逻辑,为了更改按钮,你必须更改设备。可用,而上面的代码没有。为此,我推荐两种解决方案:

  1. 懒惰的方式,性能不好:调用checkin/checkout-api成功后,再次获取整个设备列表
  2. 更多的工作但更好:在签入/签出api调用成功后,更新设备列表并再次设置设备

最新更新