DraftJS
The guide for adding multiplayer support in applications using React.js and the Draftjs editor.
Basic Integration
Start by adding codox-provider
to your DraftJS project:
The following code snippet can be copy-and-pasted into your project to create a basic integration between a Draft editor component and codox.
Codox HOC
Codox provides a high-order component withCodox(DraftEditor)
to wrap the Draft editor and furbish it with multiplayer capabilities. The HOC will perform merging and synchronization tasks automatically as editor states are mutated and when external changes are received. The only imperative interaction it has with the outside world is when to start and stop codox. The HOC expects convertFromRaw
and convertToRaw
utilities from the 'draft-js'
module passed in as helper functions.
The wrapped component expects a codoxConfig
object, the editorState
and the corresponding setEditorState
function, and the onChange
callback as props
. The editorState
the onChange
handler will be passed through to the underlying editor component directly. The setEditorState
is used by codox to update states after synchronization.
onEditorChange
The editor container would normally pass the setEditorState
function directly as the onChange
handler, which would allow Draft to directly update the local state. For instance, like so:
Or, if it chooses to provide a custom handler, that function would invoke setEditorState,
after performing something useful with the state:
With Codox acting as the layer of data merging and synchronization between the outer container component and the underlying DraftJS editor component, this data flow requires a redirection. Given that the editor state may need to be updated in response to both local and remote input, the container component or the underlying editor must not directly update the editorState
, and instead, they must delegate the update to codox
.
This is done in two ways. First, by providing a custom onChange
handler to the wrapped component, which explicitly invokes the Codox API function onEditorChange
, like so:
The only change here compared to the version with codox is to invoke codoxProviderRef.current.onEditorChange(newEditorState)
instead of setEditorState(updatedState).
Second, the setEditorState
function is passed as a prop
to the wrapped component explicitly to allow codox to finally set the controlled editorState
after any merging and updating operations are complete:
codoxProviderRef
Codox HOC provides an API layer to the outside world via forwardRef
. This ref must be defined on the container component and passed in as a prop. The actual API instance is stored in the ref as ref.current
For more usage guide, please refer to React documentation \
Starting and Stopping Codox
React is opinionated about when and where side effects can take place in a React component’s lifecycle, therefore some care is needed when invoking codox session start and stop functions.
We assume that when the application renders the editor wrapper, the latest content of the editor from the backend is either provided to the component (as a prop), or the wrapper will first perform an async fetch to obtain this content. Codox should be started after this latest content state is available for rendering. The document content is expected to be in raw JSON form, which can be transformed via the convertToDraw
on a ContentState
object.
The following code snippet illustrates the scenario where the container fetches the latest data via useEffect
:
When unmounting the editor component, invoke stop to terminate the connection to the sync service for the current user.
Rich-text and Plugins
Draftjs allows the developer to customize the basic vanilla editor with numerous plugins to support rich text editing, images, videos, @metions etc. Most plugins should work out of the box with Codox. A working example of a multiplayer Draft editor with rich-text support together with a myriad of plugins can be found here.