Mark views with React
Using Vanilla JavaScript can feel complex if you are used to work in React. Good news: You can use regular React components in your mark views, too. There is just a little bit you need to know, but let’s go through this one by one.
Render a React component
Here is what you need to do to render React components inside your editor:
- Create a mark extension
- Create a React component
- Pass that component to the provided
ReactNodeViewRenderer
- Register it with
addMarkView()
- Configure Tiptap to use your new node extension
This is how your node extension could look like:
import { Mark } from '@tiptap/core'
import { ReactMarkViewRenderer } from '@tiptap/react'
import Component from './Component.jsx'
export default Mark.create({
// options…
addMarkView() {
return ReactMarkViewRenderer(Component)
},
})
And here is an example of a React component:
import { MarkViewContent, MarkViewRendererProps } from '@tiptap/react'
import React from 'react'
export default (props: MarkViewRendererProps) => {
const [count, setCount] = React.useState(0)
return (
<span className="content" data-test-id="mark-view">
<MarkViewContent />
<label contentEditable={false}>
React component:
<button
onClick={() => {
setCount(count + 1)
}}
>
This button has been clicked {count} times.
</button>
</label>
</span>
)
}
Got it? Let’s see it in action. Feel free to copy the below example to get started.
Updating the mark view attributes
Updating your mark view's attributes is very straightforward. You can use the updateAttributes
method provided by the MarkViewRendererProps
to update the attributes of your mark view.
import { MarkViewContent, MarkViewRendererProps } from '@tiptap/react'
import React from 'react'
export default (props: MarkViewRendererProps) => {
return (
<span id={props.HTMLAttributes.id}>
<MarkViewContent />
<button onClick={() => props.updateAttributes({ id: Date.now() })}>Update ID</button>
</span>
)
}