React-markdown: Missing documentation around renderers and headings

Created on 24 Jul 2020  Â·  4Comments  Â·  Source: remarkjs/react-markdown

Hi there, I've recently started using react-markdown and am trying to using a component library. Essentially I want the paragraphs, text and headers but I'm not sure how to distinguish between h1, h2, h3 etc in the renderers?

Looking at the type NodeTypes it only supports heading, and in the documentation it says: "Heading (\

\

)" for this. But i have separate components for each h1, h2, h3, h4 etc, how can I pass all these through? I'm sure this is supported I just don't know how to do it?

Most helpful comment

@heyheman11 I was facing the same question then you, so I decided to share here how we solved

Looking into the src code I found the default resolved Heading component, and noticed that is a component that receives a children and level which indicate the heading

function Heading(props) {
  return createElement("h".concat(props.level), getCoreProps(props), props.children);
}

The solution

Create a Component which maps the default Heading to the desirable component by using the received props

interface HeadingResolverProps {
  level: number;
  children: React.ReactNode;
}

const HeadingResolver = ({ level, children }: HeadingResolverProps) => {
  const componentsByLevel = [
    Title,
    Title1,
    Title2,
    Title3,
    Headline,
    Subheadline
  ];
  const ResolvedComponent = componentsByLevel[level - 1];

  return <ResolvedComponent>{children}</ResolvedComponent>;
};

//....
const renderMapping = {
  heading: HeadingResolver,
  paragraph: Footnote
};

All 4 comments

@heyheman11 I was facing the same question then you, so I decided to share here how we solved

Looking into the src code I found the default resolved Heading component, and noticed that is a component that receives a children and level which indicate the heading

function Heading(props) {
  return createElement("h".concat(props.level), getCoreProps(props), props.children);
}

The solution

Create a Component which maps the default Heading to the desirable component by using the received props

interface HeadingResolverProps {
  level: number;
  children: React.ReactNode;
}

const HeadingResolver = ({ level, children }: HeadingResolverProps) => {
  const componentsByLevel = [
    Title,
    Title1,
    Title2,
    Title3,
    Headline,
    Subheadline
  ];
  const ResolvedComponent = componentsByLevel[level - 1];

  return <ResolvedComponent>{children}</ResolvedComponent>;
};

//....
const renderMapping = {
  heading: HeadingResolver,
  paragraph: Footnote
};

@hjJunior thank you for the extremely helpful response! Unfortunately we decided to use markdown-to-jsx https://github.com/probablyup/markdown-to-jsx instead

For anyone running into a lot of weird bugs & confusing documentation here, just like @heyheman11 I found that markdown-to-jsx immediately bypassed a lot of the frustration and seems to Just Workâ„¢

@heyheman11 I was facing the same question then you, so I decided to share here how we solved

Looking into the src code I found the default resolved Heading component, and noticed that is a component that receives a children and level which indicate the heading

function Heading(props) {
  return createElement("h".concat(props.level), getCoreProps(props), props.children);
}

The solution

Create a Component which maps the default Heading to the desirable component by using the received props

interface HeadingResolverProps {
  level: number;
  children: React.ReactNode;
}

const HeadingResolver = ({ level, children }: HeadingResolverProps) => {
  const componentsByLevel = [
    Title,
    Title1,
    Title2,
    Title3,
    Headline,
    Subheadline
  ];
  const ResolvedComponent = componentsByLevel[level - 1];

  return <ResolvedComponent>{children}</ResolvedComponent>;
};

//....
const renderMapping = {
  heading: HeadingResolver,
  paragraph: Footnote
};

I'd like to add on top of this awesome explanation with my example that includes the usage of the renderers prop:

import React from "react";
import { Header } from "semantic-ui-react";
// ...

function MyComponent(props) {

    // ...

    const input = '# This is a header\n\nAnd this is a paragraph'

    // ...

    return (
        // ...
        <ReactMarkdown
            source={input}
            renderers={{
                heading: (props) => <Header as={"h" + props.level}>{props.children}</Header>
            }}
        />
        // ...
    );
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

d0lb33 picture d0lb33  Â·  3Comments

jonjaffe picture jonjaffe  Â·  3Comments

pcvandamcb picture pcvandamcb  Â·  3Comments

neilyoung picture neilyoung  Â·  3Comments

dbuchet picture dbuchet  Â·  3Comments