Html-react-parser: Error de TS: el elemento instanceof siempre devuelve falso con Next.js

Creado en 29 ene. 2021  ·  15Comentarios  ·  Fuente: remarkablemark/html-react-parser

Demo reproducible

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

Al reemplazar a un componente personalizado, siempre se devolverá falso.

Actualmente estoy usando cualquier tipo.
Sin embargo, ¿hay alguna otra solución que no sea de ningún tipo?

question

Comentario más útil

Sigo esta instrucción y también tengo el mismo problema, no puedo obtener la propiedad attribs de domNode .

Debido a que la verificación mecanografiada domNode es una instancia de DOMNode , no Element tipo, por lo que se produce el error, porque DOMNode no tiene attribs propiedad.

Y si verifica con esta condición console.log(domNode instanceof Element) la devolución siempre es falsa, porque la instancia de domNode es DOMNode .

Tengo una solución para esto, tal vez pueda ayudar. Definí el tipo Element en el parámetro domNode.

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);
}

Todos 15 comentarios

Gracias por abrir el número @ purp1eeeee

En su ejemplo de CodeSandbox, no está devolviendo un elemento React, por lo que reemplazar no funcionará. Ver léame .

Entonces, ¿puede reemplazar los registros con una devolución de su elemento personalizado?

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>;
 }

Consulte CodeSandbox actualizado.

Sigo esta instrucción y también tengo el mismo problema, no puedo obtener la propiedad attribs de domNode .

Debido a que la verificación mecanografiada domNode es una instancia de DOMNode , no Element tipo, por lo que se produce el error, porque DOMNode no tiene attribs propiedad.

Y si verifica con esta condición console.log(domNode instanceof Element) la devolución siempre es falsa, porque la instancia de domNode es DOMNode .

Tengo una solución para esto, tal vez pueda ayudar. Definí el tipo Element en el parámetro domNode.

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);
}

Puedo confirmar que tengo el mismo problema con un proyecto Next.js; La conversión de tipos de mecanografiado domNode parece ser la única solución después de actualizar html-react-parser.

@kakaeriel
¡tan bueno! gracias

Tener estos problemas con un proyecto de TypeScript. Al igual que @kakaeriel , sigo estas instrucciones sobre la sustitución, incluida la sección de Typecript.

La solución de @kakaeriel funciona para mí. El operador instanceof no funciona (Element no es un tipo) y después de horas navegando a través de node_modules buscando una definición de tipo, encontrar esta solución es un salvavidas.

Gracias por proporcionar una solución alternativa @kakaeriel. ¿Estaría interesado en crear un PR para mejorar la documentación README.md ?

@remarkablemark ¡ Sí, claro! Crearé un PR, lo antes posible.

Guau. Tengo el mismo problema al usar NextJS.

Debido a que la verificación mecanografiada domNode es una instancia de DOMNode , no Element tipo, por lo que se produce el error, porque DOMNode no tiene attribs propiedad.

''

Entonces, ¿por qué esto solo ocurre en una aplicación NextJS?
Configuré una aplicación mecanografiada react-scripts y ahí funciona.
https://codesandbox.io/s/html-parsing-and-replacing-elements-yjtv7?file=/src/index.tsx

No estoy seguro @ Naxos84. Apuesto a que Next.js tiene una configuración de TypeScript diferente. Consulte la solución de @kakaeriel para encontrar una solución.

@kakaeriel, avíseme si puede abrir un PR para actualizar el README.md con su solución. Si no puede hacerlo, puedo hacerlo. ¡Gracias!

No creo que esté relacionado con NextJs.
Intenté un poco más y listo, funcionó de alguna manera.
Cambié @remarkablemark codesandbox y agregué console.log(domElement.constructor) como se menciona en Stack Overflow .

El resultado es el siguiente:
grafik

¿¡Entonces no entiendo por qué de repente está funcionando !?

Aunque no funciona en "mi" proyecto nextjs.
Actualización: Y ahora no vuelve a funcionar ...

Sugiero usar un tipo de protección personalizado.

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>;
        }
    },
};

Hola a todos, pude solucionar esto en Next.js 10.x con esta solución . Es un Gist público donde puede encontrar mis detalles de implementación actuales. La solución tiene cero errores de tipo en mi configuración.

@natterstefan ¡ Gracias por compartir su solución!

Tengo el mismo problema con NextJS. El elemento siempre está indefinido. Escribí domNode como cualquiera y convertí el tipo de opciones como HTMLReactParserOptions. ¿El elemento de domhandler no funciona con SSR?

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

Pude solucionar este problema con el siguiente código, espero que ayude

Screen Shot 2021-06-12 at 20 32 31

¿Fue útil esta página
0 / 5 - 0 calificaciones