1. Achieve results
Recently, I am writing a blog management system with React. One function is to add new articles. On the new article page, I want to do something like CSDN. On the left is the editing area (markdown format) and on the right is the preview area. Update in real time. While editing the text, you can see the effect in the preview area.
I implemented such a component myself, markdown real-time preview editor!
The specific effects are as follows:
2. Implementation process
It is realized by React and made into a separate component.
First, the HTML structure is as follows:
<header>be based on React of markdown Real time editor</header> <div className="marked"> {/* Edit area */} <div className="input-region markdownStyle"></div> {/* Preview area */} <div className="show-region markdownStyle"></div> </div>
Write a little style to make the editing area and preview area layout left and right.
Define a hook to store the input content:
const [text, setText] = useState('');
In the left editing area, make a div editable, add the contentEditable attribute to it, and set the value to plaintext only, which means that only plain text can be entered in the editing area.
<div className="input-region markdownStyle" contentEditable="plaintext-only"></div>
Why not use textarea:
div is highly adaptive and can get plain text.
When the content of the editing area on the left changes, store the input plain text into state, add onInput attribute to the div in the editing area, and get the plain text through the event object:
<div className="input-region markdownStyle" contentEditable="plaintext-only" onInput={e => { setText(e.target.innerText); }} ></div>
To render the content in markdown format, you need a plug-in to render it. Here, marked is used, and code highlighting is also required. Highlight js:
yarn add marked highlight.js
import marked from 'marked'; import hljs from 'highlight.js';
To configure marked and highlight:
useEffect(() => { // Configure highlight hljs.configure({ tabReplace: '', classPrefix: 'hljs-', languages: ['CSS', 'HTML', 'JavaScript', 'Python', 'TypeScript', 'Markdown'], }); // Configure marked marked.setOptions({ renderer: new marked.Renderer(), highlight: code => hljs.highlightAuto(code).value, gfm: true, //The default is true. Allow the markdown of Git Hub standard tables: true, //The default is true. Allow support for table syntax. This option requires gfm to be true. breaks: true, //The default is false. Carriage return is allowed. This option requires gfm to be true. }); }, []);
github style code was introduced to highlight the theme, but I made some modifications myself:
import './github-dark.css';
In the preview area, use the label attribute dangerouslySetInnerHTMl of React to display the content:
<div className="show-region markdownStyle" dangerouslySetInnerHTML={{ __html: marked(text).replace(/<pre>/g, "<pre id='hljs'>"), }} ></div>
Call marked to render the text in markdown format. replace is added because I found that the background color of the code box is not displayed after rendering, so I added an id to the < pre > tag, and then wrote my own CSS to display the background of the code box.
After the whole component is written, the final code:
import { useState, useEffect } from 'react'; import marked from 'marked'; import hljs from 'highlight.js'; import './github-dark.css'; import './index.css'; const Marked = () => { const [text, setText] = useState(''); useEffect(() => { // Configure highlight hljs.configure({ tabReplace: '', classPrefix: 'hljs-', languages: ['CSS', 'HTML', 'JavaScript', 'Python', 'TypeScript', 'Markdown'], }); // Configure marked marked.setOptions({ renderer: new marked.Renderer(), highlight: code => hljs.highlightAuto(code).value, gfm: true, //The default is true. Allow the markdown of Git Hub standard tables: true, //The default is true. Allow support for table syntax. This option requires gfm to be true. breaks: true, //The default is false. Carriage return is allowed. This option requires gfm to be true. }); }, []); return ( <> <header>be based on React of markdown Real time editor</header> <div className="marked"> <div className="input-region markdownStyle" contentEditable="plaintext-only" // suppressContentEditableWarning onInput={e => { setText(e.target.innerText); }} ></div> <div className="show-region markdownStyle" dangerouslySetInnerHTML={{ __html: marked(text).replace(/<pre>/g, "<pre id='hljs'>"), }} ></div> </div> </> ); }; export default Marked;
3. Source code
Other codes, such as code highlight theme files and style files, including the whole source code, are placed in the [Github] You need to take it yourself.
If it helps you, take care ❤️~
📘📘 Welcome to my blog:
https://lzxjack.top/