我有一个钩子可以在应用程序中显示一系列警报。每次我调用钩子推送数组并显示新警报时,它都可以正常工作,但如果我想从子组件中删除此警报,则调用父钩子函数不起作用。
这是警报组件。 “closeAlert”道具是调用父钩子函数的道具。 该方法被调用,它从数组中删除我想要的元素,但它不会使用数组的新值呈现
import React from 'react';
import { Alert, Button } from '@themesberg/react-bootstrap';
import { memo } from 'react';
import { createPortal } from 'react-dom';
const Alerts = memo(({ content, closeAlert, i }) => {
const domEl = document.getElementById('alerts')
if (!domEl) return null
return createPortal(
<React.Fragment>
<Alert
variant="primary">
<div className="d-flex align-items-center justify-content-between">
<div className="font-small">
{content.body}
</div>
<Button variant="close" size="xs" onClick={() => closeAlert(i)} />
</div>
</Alert>
</React.Fragment>,
domEl
);
})
export default Alerts;
这是钩子。当我调用 Alerts 组件时,我将“handleCloseAlert”函数作为道具传递。正如我在上一点所说的。从警报中,它可以毫无问题地调用此函数,并删除所需的“hiddenAlerts”数组元素,但永远不会在“RenderAlert”中更新或呈现它
import React from 'react';
import { useState } from 'react';
import { Fragment } from 'react';
import Alerts from '../components/Alerts';
const useAlert = () => {
const [hiddenAlerts, setHiddenAlerts] = useState([]);
const handleShowAlert = (alertId) => {
const hiddenAlertsUpdated = [...hiddenAlerts, alertId];
setHiddenAlerts(hiddenAlertsUpdated);
};
const handleCloseAlert = (alertId) => {
const alerts = hiddenAlerts;
alerts.splice(alertId, 1);
setHiddenAlerts(alerts);
};
const RenderAlert = () => (
<Fragment>
{
hiddenAlerts.map((res, index) => {
return <Alerts key={index} content={res} i={index} closeAlert={handleCloseAlert}></Alerts>
})
}
</Fragment>
)
return {
handleShowAlert,
handleCloseAlert,
RenderAlert
}
};
export default useAlert;
从这里我调用钩子
export default (props) => {
const { handleShowAlert, RenderAlert } = useAlert();
const open = () => {
const alert = new AlertModal(
"Alert test",
'',
Constants.TYPE_ALERT.warning
)
handleShowAlert(alert);
}
return (
<div>
<Button variant="primary" type="button" onClick={open} className="w-100">Abrir modal</Button>
<RenderAlert>
</RenderAlert>
</div>
)
}
从已经非常感谢你
答案 0 :(得分:0)
可能问题出在修改当前数组的splice
函数的使用,所以hiddenAlerts
数组保持相同的引用。您可以改为使用 filter
函数创建一个新数组,如下所示:
const handleCloseAlert = i => {
const newAlerts = hiddenAlerts.filter((_, index) => i !== index);
setHiddenAlerts(newAlerts);
};
答案 1 :(得分:0)
这是因为在您的 handleCloseAlert
实现中,alerts
是对您的状态对象 hiddenAlerts
的引用。执行 splice
并使用 setHiddenAlerts(alerts)
更新状态确实如此不会触发状态更改,因为 react 在 hiddenAlerts
中看不到任何变化(因为 alerts
也是相同的 [reference] )
你可以试试下面的实现
const handleCloseAlert = (alertId) => {
setHiddenAlerts(hiddenAlerts.filter((_, index) => index !== alertId));
};
此外,尝试将此实现更改为不依赖于数组索引值。尝试使用像 uuid