Draft JS: Getting Started

Evgenia Karunus
2 min readMar 3, 2017

--

Attention: Medium’s editor is painful, so I created a page with properly formatted contents of this tutorial: https://lakesare.github.io/draft-rendering-methods.

What is a content block? codepen

In Draft, content block is a javascript object inside <Editor/>'s state (that we are keeping in our component and pass as Editor.props.editorState). We can take a look at what contentBlocks our <Editor/> has by logging convertToRaw(this.state.editorState.getCurrentContent()) to console.

If we seed our editor with <h6>Hii</h6>, it will return, among other stuff, something like this:

blocks: [
{ // content block
text: "Hii"
type: "header-six"
}, {}, {}
]

So "header-six" type corresponds to <h6> html tag. To determine what content block's type refers to what html tag, refer to https://github.com/facebook/draft-js/blob/16ed6e5a1e7c9d5a0d5718b9a50c8256ee33f938/src/model/immutable/DefaultDraftBlockRenderMap.js (well, or check it with this codepen).

Once again: content block is an object in editor’s state. When <Editor/> renders its state into some actual html we are seeing, it will look at content block's type, map it to some tag (header-six => <h6>), and show it.

What does it even mean to customly render a block? codepen

Look at our codepen. We seeded our Editor with some contentState (by transforming html to the usual contentState object Editor understands). Then Editor needed to transform every content block of contentState to some html tag to display it to us. By default, content block of type header-six will be transformed to h6. This process can be controlled by the 3 properties passed to <Editor/> we will be discussing here: blockStyleFn, blockRenderMap and blockRendererFn. Fundamentally they all do the same: they determine the way content block is displayed to us as html.

When to use each of these props?

blockStyleFn

When? We want to look at any of the content block’s properties (type, text, data), and add a css class to the rendered html.

Example of usage: Eg we want every h1 with text 'Wow' to have yellow background.

Code: codepen

(contentBlock) = {
if (contentBlock.getText() === 'Hii') {
return 'cssClassToUseOnEveryHii';
}
}

blockRenderMap

When? We want to look at content block’s type (eg header-six), but render something other than h6 - maybe plain div, or even our own react component.

Example of usage: Eg we want every blockquote to be rendered as MyComponent instead.

Code: codepen for html tag, codepen for our own component

DefaultDraftBlockRenderMap.merge(
Immutable.Map({
'header-six': {
element: 'h1', // or
wrapper: MyComponent
}
})
);

blockRendererFn

When? We want to look at any of the content block’s properties (type, text, data), and render our own react component based on them.

Example of usage:
Eg we want content block with { type: 'flowerImage', data: { color: 'blue' } to be rendered as MyBlueFlowerComponent

Code: codepen

const type = contentBlock.getType();
if (type === 'header-six') {
return {
component: MyComponent,
props: {
plainText: contentBlock.getText()
}
};
}

--

--

Responses (7)