Heim > Fragen und Antworten > Hauptteil
Ich habe einen benutzerdefinierten Hook useNotifications
für ein Benachrichtigungs-Widget. Dieser Hook gibt ein Array zurück, das das nächste Element enthält (ähnlich der ant.design-Messaging-API):
add
: Funktion zum Hinzufügen einer neuen Benachrichtigungremove
: Funktion zum Abrufen der Benachrichtigungs-ID und zum Löschen der BenachrichtigungcontextHandler
: JSX wird an das Komponenten-Rendering übergebenWenn der Benutzer anruft add
, erhält er eine ID, mit der er die Benachrichtigung löschen kann
Diese Frage bezieht sich speziell auf die Löschfunktion. Da ich diese Funktion direkt nach dem Hinzufügen einer neuen Benachrichtigung aufrufe, erhält die Funktion eine Kopie der alten Liste, also keine neuen Elemente, und es wird ein Fehler ausgegeben. Wie kann ich das Problem beheben, sodass die Komponenten dieselbe API verwenden?
useNotification-Hook Wie verwende ich es
Codesandbox (zum Testen habe ich gemacht setTimeout
,它在3秒内调用了remove()
): https://codesandbox.io/s/goofy-smoke-5q7dw3?file=/src/App.js:405-440
P粉4781887862023-09-13 00:58:59
您可以使您的 remove
函数使用 状态更新器功能,可以访问最新的状态值。这允许您在组件在 remove()
中重新渲染之前访问新的 list
状态。
注意:您当前正在通过将嵌套对象的 isMounted
属性设置为 false
来改变原始状态。即使您复制了数组,您也应该复制正在更新的对象,以避免重新渲染问题。
以下是有关如何访问状态的最新值并避免状态突变的一些修改:
const add = useCallback((params) => { const id = v4(); const element = {...params, id, isMounted: true}; setList(list => [...list, element]); // Add your new element while also making a copy of the current state (`list`) return id; }, []); const remove = useCallback((elementId) => { setList((list) => list.map((elem) => elem.id === elementId ? { ...elem, isMounted: false } : elem ) ); setTimeout(() => { setList((list) => list.filter((elem) => elem.id !== elementId)); }, 500); }, []);
参见下面的示例: