This guide explains how to add multiplayer support to applications using React.js and the Draft.js editor.
Basic Integration
Start by adding draft-provider to your DraftJS project:
The following code snippet outlines how to establish basic integration between a Draft editor component and Codox:
Codox HOC
Codox provides the withCodox(DraftEditor) HOC to integrate multiplayer functionality into the Draft.js editor. This HOC automates merging and synchronization as editor states change due to local modifications or external updates. It manages the starting and stopping of the collaboration session (synchronization process).
The withCodox HOC wraps a Draft.js Editor component, enabling it to receive and handle updates from both local user interactions and remote changes. It expects editorState, setEditorState, and onChange as props:
editorState: Current state of the editor.
setEditorState: Function to update the editor state after synchronization.
onChange: Handler for editor state changes.
Handling Editor State Changes
In a typical Draft.js implementation, the editor state is updated directly via the onChange handler provided to the Editor. For example:
Or, if it chooses to provide a custom handler, that function would invoke setEditorState, after performing something useful with the state:
When integrating with Codox, the flow of updating the editor state is redirected to ensure that all local user’s and remote users’ inputs are reconciled correctly. This is achieved by:
Custom onChange Handling: Instead of directly updating the editor state, this handler will invoke codoxAPI.current.onEditorChange, which manages the state internally and ensures that all changes (both local and remote) are synchronized.
Setting Editor State: The setEditorState function is explicitly passed as a prop to the wrapped component. This setup allows Codox to apply the editor state post-merging and synchronization, ensuring that the editor reflects the most recent and accurate state of the document.
codoxAPI
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’s lifecycle conventions dictate specific practices for handling side effects, making it crucial to consider when and how to initiate or terminate Codox sessions.
Typically, the editor wrapper component retrieves the latest document content from the backend, either directly as a prop or through an asynchronous fetch operation. It is essential that Codox is started only after this content is fully loaded and ready for rendering. The content should be provided in JSON format, suitable for transformation into Draft’s ContentState via convertToRaw.
The following snippet demonstrates fetching the latest document state and managing the Codox session lifecycle:
When unmounting the editor component, invoke stop to terminate the connection to the sync service for the current user.
Rich-text and Plugins
Draft.js allows for extensive customization and enhancement through various plugins that support rich text features, images, videos, @mentions, and more. Most of these plugins are compatible with Codox right out of the box, allowing for a seamless integration into a multiplayer environment.
For a practical implementation example, visit the following GitHub repository which features a working example of a multiplayer Draft editor enriched with various plugins: Codox Draft Extended Example.
Events
Developers can tap into a variety of events emitted by Codox to handle synchronization states, user interactions, and errors more efficiently. It’s important to subscribe to these events before starting the Codox session to ensure all events are captured. Here’s how to integrate these event subscriptions into your application:
Preparing to Subscribe
Before initiating the Codox session with codoxAPI.start(), subscribe to the desired events. This setup ensures that your application is prepared to handle updates and changes from the moment the session begins.
Important Notes
Event Timing: Subscribing to events after invoking codoxAPI.start() may result in missing initial events or updates that occur right at the start of the session.
Handling Multiple Subscriptions: If your component could potentially re-subscribe due to re-rendering, ensure that you handle event subscription and unsubscription properly to avoid duplicate handlers.