ReactJS – Die benutzerdefinierte Hook-Return-Funktion speichert keine tatsächlichen Daten des internen Status
P粉729436537
P粉729436537 2023-09-12 08:49:22
0
1
496

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 Benachrichtigung
  • remove: Funktion zum Abrufen der Benachrichtigungs-ID und zum Löschen der Benachrichtigung
  • contextHandler: JSX wird an das Komponenten-Rendering übergeben

Wenn 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粉729436537
P粉729436537

Antworte allen(1)
P粉478188786

您可以使您的 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);
}, []);

参见下面的示例:

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage