Html-react-parser: TS Error: instanceof Element gibt immer false mit Next.js zurück

Erstellt am 29. Jan. 2021  ·  15Kommentare  ·  Quelle: remarkablemark/html-react-parser

Reproduzierbare Demo

https://codesandbox.io/s/quizzical-lake-16q4o?file=/pages/index.tsx

Beim Ersetzen durch eine benutzerdefinierte Komponente wird immer false zurückgegeben.

Ich verwende derzeit den beliebigen Typ.
Gibt es jedoch eine andere Lösung als die beliebige Art?

question

Hilfreichster Kommentar

Ich folge dieser Anweisung und habe auch das gleiche Problem, ich kann die Eigenschaft attribs von domNode .

Da die Typoskriptprüfung domNode eine Instanz von DOMNode und nicht Element ist, tritt der Fehler auf, weil DOMNode nicht attribs Eigentum.

Und wenn Sie mit dieser Bedingung console.log(domNode instanceof Element) überprüfen, wird immer false zurückgegeben, da die Instanz von domNode DOMNode .

Ich habe eine Lösung dafür, kann vielleicht helfen. Ich habe den Typ Element am Parameter domNode definiert.

import parse, { HTMLReactParserOptions } from "html-react-parser";
import { Element } from "domhandler/lib/node";

export function contentHandler(postContent: string) {
  const options: HTMLReactParserOptions = {
    replace: (domNode: Element) => {
      if (domNode.attribs) {
        if (domNode.attribs.id === 'shortcode') {
          return <div className="leadform">Shortcode</div>;
        }
      }
    },
  };

  return parse(postContent, options);
}

Alle 15 Kommentare

Danke für das Öffnen der Ausgabe @purp1eeeee

In Ihrem CodeSandbox-Beispiel geben Sie kein React-Element zurück, sodass das Ersetzen nicht funktioniert. Siehe Readme .

Können Sie also die Protokolle durch eine Rückgabe Ihres benutzerdefinierten Elements ersetzen?

export default function IndexPage() {
   const html = "<h1>hoge</h1>";
   const options: HTMLReactParserOptions = {
     replace: (domNode) => {
-      console.log(domNode);
-      console.log(domNode instanceof Element);
+      if (domNode.name === "h1") {
+        return <h1>replaced</h1>;
+      }
     }
   };
   return <div>{parse(html, options)}</div>;
 }

Siehe aktualisierte CodeSandbox .

Ich folge dieser Anweisung und habe auch das gleiche Problem, ich kann die Eigenschaft attribs von domNode .

Da die Typoskriptprüfung domNode eine Instanz von DOMNode und nicht Element ist, tritt der Fehler auf, weil DOMNode nicht attribs Eigentum.

Und wenn Sie mit dieser Bedingung console.log(domNode instanceof Element) überprüfen, wird immer false zurückgegeben, da die Instanz von domNode DOMNode .

Ich habe eine Lösung dafür, kann vielleicht helfen. Ich habe den Typ Element am Parameter domNode definiert.

import parse, { HTMLReactParserOptions } from "html-react-parser";
import { Element } from "domhandler/lib/node";

export function contentHandler(postContent: string) {
  const options: HTMLReactParserOptions = {
    replace: (domNode: Element) => {
      if (domNode.attribs) {
        if (domNode.attribs.id === 'shortcode') {
          return <div className="leadform">Shortcode</div>;
        }
      }
    },
  };

  return parse(postContent, options);
}

Ich kann bestätigen, dass ich dasselbe Problem mit einem Next.js-Projekt habe. Typescript Type-Casting domNode scheint die einzige Problemumgehung nach dem Upgrade von html-react-parser zu sein.

@kakaeriel
so gut! danke👍

Habe diese Probleme mit einem Typescript-Projekt. Wie @kakaeriel befolge ich diese Anweisung zum Ersetzen, einschließlich des Abschnitts zu Typoskript.

Die Lösung von @kakaeriel funktioniert bei mir. Der Operator instanceof funktioniert nicht (Element ist kein Typ) und nach stundenlangem Durchsuchen von node_modules auf der Suche nach einer Typdefinition ist es ein Lebensretter, diese Problemumgehung zu finden.

Vielen Dank für die Bereitstellung einer alternativen Lösung @kakaeriel. Wären Sie daran interessiert, eine PR zu erstellen, um die README.md Dokumentation zu verbessern?

@remarkablemark Ja sicher! Ich werde so schnell wie möglich eine PR erstellen.

Beeindruckend. Ich habe das gleiche Problem mit NextJS.

Da die Typoskriptprüfung domNode eine Instanz von DOMNode und nicht Element ist, tritt der Fehler auf, weil DOMNode nicht attribs Eigentum.

```

Warum tritt dies nur in einer NextJS-App auf?
Ich habe eine Typskript-App für React-Scripts eingerichtet und dort funktioniert es.
https://codesandbox.io/s/html-parsing-and-replacing-elements-yjtv7?file=/src/index.tsx

Ich bin mir nicht sicher @Naxos84. Ich wette, Next.js hat eine andere TypeScript-Konfiguration. Bitte sehen Sie sich die Lösung von @kakaeriel an , um eine Problemumgehung zu erhalten.

@kakaeriel lass es mich wissen, wenn du eine PR öffnen kannst, um die README.md mit deiner Problemumgehung zu aktualisieren. Wenn Sie es nicht können, kann ich es tun. Vielen Dank!

Ich glaube nicht, dass es mit NextJs zusammenhängt.
Ich habe noch ein bisschen versucht und voila es hat irgendwie funktioniert.
Ich habe @remarkablemark console.log(domElement.constructor) hinzugefügt, wie in Stack Overflow erwähnt .

Das Ergebnis sieht wie folgt aus:
grafik

Also ich verstehe nicht warum es plötzlich funktioniert!?

Obwohl es in "meinem" nextjs-Projekt nicht funktioniert.
Update: Und jetzt geht es wieder nicht....

Ich schlage vor, einen benutzerdefinierten Typeguard zu verwenden.

const isElement = (domNode: DOMNode): domNode is Element => {
    const isTag = domNode.type === "tag";
    const hasAttributes = (domNode as Element).attribs !== undefined;

    return isTag && hasAttributes;
};
const parserOptions: HTMLReactParserOptions = {
    replace: domNode => {
        if (isElement(domNode)) {
            return <p>It's an element.</p>;
        } else {
            return <p>It's something else</p>;
        }
    },
};

Hallo zusammen, ich konnte dies in Next.js 10.x mit dieser Lösung beheben. Es ist ein öffentlicher Gist, in dem Sie meine aktuellen Implementierungsdetails finden. Die Lösung hat null Typfehler in meinem Setup.

@natterstefan Danke für das Teilen deiner Lösung!

Ich habe das gleiche Problem mit NextJS. Element ist immer undefiniert. Ich habe domNode als any eingegeben und den Optionstyp als HTMLReactParserOptions konvertiert. Element von domhandler funktioniert nicht mit SSR?

const options = {
  replace: (domNode: any) => {
      // ...
  }
} as HTMLReactParserOptions;

Ich konnte dies mit dem folgenden Code beheben, hoffe es würde helfen

Screen Shot 2021-06-12 at 20 32 31

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen