Html-react-parser: Erro de TS: o elemento instanceof sempre retorna falso com Next.js

Criado em 29 jan. 2021  ·  15Comentários  ·  Fonte: remarkablemark/html-react-parser

Demonstração reproduzível

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

Ao substituir para um componente personalizado, false sempre será retornado.

Atualmente estou usando qualquer tipo.
No entanto, existe alguma outra solução diferente de qualquer tipo?

question

Comentários muito úteis

Seguindo esta instrução , e também tenho o mesmo problema, não consigo obter a propriedade attribs de domNode .

Porque a verificação de texto digitado domNode é uma instância do tipo DOMNode , não Element , de modo que o erro ocorre, porque DOMNode não tem attribs propriedade.

E se você verificar com esta condição console.log(domNode instanceof Element) o retorno sempre é falso, porque a instância de domNode é DOMNode .

Tenho solução para isso, talvez possa ajudar. Eu defini o tipo Element no 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 comentários

Obrigado por abrir a edição @ purp1eeeee

Em seu exemplo CodeSandbox, você não está retornando um elemento React, portanto, substituir não funcionará. Veja o leia-me .

Então, você pode substituir os logs por um retorno de seu 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>;
 }

Veja CodeSandbox atualizado.

Seguindo esta instrução , e também tenho o mesmo problema, não consigo obter a propriedade attribs de domNode .

Porque a verificação de texto digitado domNode é uma instância do tipo DOMNode , não Element , de modo que o erro ocorre, porque DOMNode não tem attribs propriedade.

E se você verificar com esta condição console.log(domNode instanceof Element) o retorno sempre é falso, porque a instância de domNode é DOMNode .

Tenho solução para isso, talvez possa ajudar. Eu defini o tipo Element no 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);
}

Posso confirmar que estou tendo o mesmo problema com um projeto Next.js. A conversão de tipo de texto digitado domNode parece ser a única solução após a atualização do html-react-parser.

@kakaeriel
tão bom! obrigada👍

Tendo esses problemas com um projeto Typescript. Como @kakaeriel , estou seguindo esta instrução sobre a substituição, incluindo a seção sobre o texto datilografado .

A solução da @kakaeriel funciona para mim. O operador instanceof não funciona (Elemento não é um tipo) e depois de horas navegando por node_modules procurando por uma definição de tipo, encontrar esta solução alternativa salva vidas.

Obrigado por fornecer uma solução alternativa @kakaeriel. Você estaria interessado em criar um PR para melhorar a documentação README.md ?

@remarkablemark Sim, claro! Vou criar um PR, o mais rápido possível.

Uau. Tenho o mesmo problema ao usar o NextJS.

Porque a verificação de texto digitado domNode é uma instância do tipo DOMNode , não Element , de modo que o erro ocorre, porque DOMNode não tem attribs propriedade.

`` `

Então, por que isso ocorre apenas em um aplicativo NextJS.
Eu configurei um aplicativo typescript react-scripts e ele funciona.
https://codesandbox.io/s/html-parsing-and-replacing-elements-yjtv7?file=/src/index.tsx

Não tenho certeza @ Naxos84. Aposto que Next.js tem uma configuração TypeScript diferente. Verifique a solução de @kakaeriel para uma solução alternativa.

@kakaeriel, deixe-me saber se você consegue abrir um PR para atualizar o README.md com sua solução alternativa. Se você não puder fazer isso, eu posso fazer. Obrigado!

Não acho que seja relacionado ao NextJs.
Tentei um pouco mais e voilá funcionou de alguma forma.
Mudei @remarkablemark codesandbox e adicionei console.log(domElement.constructor) conforme mencionado no Stack Overflow .

O resultado é o seguinte:
grafik

Então eu não entendo porque de repente está funcionando !?

Embora não esteja funcionando no projeto "meu" nextjs.
Atualização: E agora não está funcionando novamente ....

Eu sugiro usar um protetor de tipo 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>;
        }
    },
};

Olá a todos, consegui consertar isso no Next.js 10.x com esta solução . É um Gist público onde você pode encontrar meus detalhes de implementação atuais. A solução não tem erros de tipo em minha configuração.

@natterstefan Obrigado por compartilhar sua solução!

Tenho o mesmo problema com o NextJS. O elemento é sempre indefinido. Digitei domNode como qualquer e converti o tipo de opções como HTMLReactParserOptions. O elemento de domhandler não funciona com SSR?

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

Consegui corrigir isso com o código abaixo, espero que ajude

Screen Shot 2021-06-12 at 20 32 31

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

shiglet picture shiglet  ·  6Comentários

rscott78 picture rscott78  ·  11Comentários

on2air picture on2air  ·  3Comentários

christianfredh picture christianfredh  ·  5Comentários

dave-stevens-net picture dave-stevens-net  ·  9Comentários