Объявление настраиваемого компонента React-Markdown, как я могу объявить в средстве визуализации для использования настраиваемого компонента?

Проблема

Используя React-Markdown, я могу полностью использовать свои собственные компоненты. Но это с конкретными заранее созданными ключевыми словами в уценке. Как абзац или изображения. Это работает ОТЛИЧНО. Но проблема в том, что все они кажутся заранее созданными словами / условиями, такими как абзацы, заголовки или изображения.

Я не могу найти способ добавить что-нибудь новое ключевое слово в мою уценку, например «CustomComponent», которое будет использоваться. Это все, что мне нужно на данный момент><

Это прекрасно работает для меня, чтобы превратить изображение уценки в специальный компонент «нижний колонтитул», который я сделал где-то еще. Я знаю, что это смешно, но это работает. Но я понятия не имею, как заставить этот рендерер принимать / создавать новое ключевое слово, например «emoji», «customComponent» или «somethingSilly».

      let body = 
    `![Fullstack React](https://dzxbosgk90qga.cloudfront.net/fit-in/504x658/n/20190131015240478_fullstack-react-cover-medium%402x.png)`;

const renderers = {
    image: () => <Footer/>
};

<ReactMarkdown source={body} renderers={renderers} />;

Некоторые прошлые работы, которые я сделал:

Некоторая документация:https://reposhub.com/react/miscellaneous/rexxars-react-markdown.html https://github.com/rexxars/commonmark-react-renderer/blob/master/src/commonmark-react-renderer.js#L50

Примеры:https://codesandbox.io/s/react-markdown-with-custom-renderers-961l3?from-embed=&amp;file=/src/App.js.

Но ничто не указывает на то, как я могу использовать «CustomComponent», чтобы указать, что нужно внедрить специальный компонент.

Пример использования / фон

Я пытаюсь получить статью из своей базы данных, которая отформатирована таким же образом в разметке (в основном это гигантская строка). Я использую обычную реакцию с машинописным текстом и сокращением - это единственная часть моего приложения, которая в этом нуждается.

      "
# Title

## Here is a subtitle

Some text

<CustomComponentIMade/>

Even more text after.


<CustomComponentIMade/>

"

2 ответа

Я знаю, что это, скорее всего, немного поздно для ваших целей, но мне удалось решить эту проблему с помощью специального компонента примечания.

По сути, вам нужно будет использовать плагин, а также небольшой настраиваемый плагин замечаний (я получил этот плагин прямо из remark-directive документы)

Затем в ответной уценке вы можете указать плагины, настраиваемые средства визуализации и настраиваемые теги, например.

      import React from 'react'
import ReactMarkdown from 'react-markdown'
import {render} from 'react-dom'
import directive from 'remark-directive'
import { MyCustomComponent } from './MyCustomComponent'

// react markdown components list
const components = {
  image: () => <Footer/>,
  myTag: MyCustomComponent
}

// remark plugin to add a custom tag to the AST
function htmlDirectives() {
  return transform

  function transform(tree) {
    visit(tree, ['textDirective', 'leafDirective', 'containerDirective'], ondirective)
  }

  function ondirective(node) {
    var data = node.data || (node.data = {})
    var hast = h(node.name, node.attributes)

    data.hName = hast.tagName
    data.hProperties = hast.properties
  }
}

render(
  <ReactMarkdown components={components} remarkPlugins={[directive, htmlDirectives]}>
    Some markdown with a :myTag[custom directive]{title="My custom tag"}
  </ReactMarkdown>,
  document.body
)

Итак, в вашей уценке везде, где у вас есть что-то вроде :myTag[...]{...attributes} вы должны сделать MyCustomComponent с участием attributes как реквизит.

Извините, я не тестировал код, но, надеюсь, он передает суть вещей. Если вам нужен рабочий пример, дайте мне знать, и я сделаю все возможное, чтобы его настроить.

Я пробовал этот способ, и это сработало для меня

      import CustomNextImage from '@commonComponentsDependent/CustomNextImage';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { FC } from 'react';
import ReactMarkdown from 'react-markdown';
import { Options } from 'react-markdown/lib/ast-to-react';
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
import remarkGfm from 'remark-gfm';

const SyntaxHighlighterDynamic = dynamic(() => import('./SyntaxHighlighter'));

import classes from './styles.module.css';

interface Props {
    content: string;
}

type TCustomComponents = Options['components'];
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

const MdToHTML: FC<Props> = ({ content }) => {
    const customComponents: TCustomComponents = {
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        img(image) {
            if (!image.src) return <></>;

            return (
                <div className={classes['img-container']}>
                    <CustomNextImage
                        src={image.src}
                        alt={image.alt}
                    />
                </div>
            );
        },

        a({ href, children, node }) {
            if (!href) return <></>;

            if (
                href.startsWith('/') ||
                href.startsWith('https://lognmaze.com')
            ) {
                return (
                    <Link href={href} prefetch={false} passHref>
                        <a>{children}</a>
                    </Link>
                );
            }

            return (
                <a
                    href={href}
                    target='_blank'
                    rel='noopener noreferrer'
                >
                    {children}
                </a>
            );
        },

        code({ node, inline, className, children, ...props }) {
            const match = /language-(\w+)/.exec(className || '');

            return !inline && match ? (
                <SyntaxHighlighterDynamic language={match[1]} PreTag='div' {...props}>
                    {String(children).replace(/\n$/, '')}
                </SyntaxHighlighterDynamic>
            ) : (
                <code className={className} {...props} data-code-inline='true'>
                    {children}
                </code>
            );
        },
    };

    return (
        <ReactMarkdown
            components={customComponents}
            remarkPlugins={[remarkGfm]}
        >
            {content}
        </ReactMarkdown>
    );
};

export default MdToHTML;
Другие вопросы по тегам