Draft.js最佳实践:数据库存储与EditorState体积优化问题
Hey there! Let's break down your two Draft.js questions with practical, straightforward solutions:
1. Best way to store Draft.js text in a database
Great news—your current implementation is actually the official recommended method and works perfectly for preserving all editor content details. Here's a deeper dive into why it’s reliable, plus a clear breakdown of the flow:
How the workflow works:
- Saving to database: Convert your
EditorStateto a raw JavaScript object usingconvertToRaw()—this captures every detail like text styles, links, block types, and entity data. Then stringify the object to JSON for easy storage in any database (SQL or NoSQL). - Loading from database: Retrieve the stored JSON string, parse it back into an object, use
convertFromRaw()to turn it into aContentState, and finally create a newEditorStatewithEditorState.createWithContent().
Example code:
// Saving to database const rawContent = convertToRaw(myEditorState.getCurrentContent()); const serializedContent = JSON.stringify(rawContent); // Store serializedContent in your database (e.g., PostgreSQL, MongoDB) // Loading from database const storedContent = await fetchFromDatabase(); // Fetch the saved JSON string const parsedRawContent = JSON.parse(storedContent); const loadedContentState = convertFromRaw(parsedRawContent); const loadedEditorState = EditorState.createWithContent(loadedContentState);
This method is fully compatible with all Draft.js-based editors like react-rte, react-draft-wysiwyg, and draftail—since they all build on Draft.js’s core data structures, the same conversion logic applies seamlessly.
2. Limiting line breaks to reduce EditorState volume
Excessive empty line breaks can bloat your EditorState size, especially if users hit enter multiple times. Here are two effective ways to fix this:
Option 1: Clean content before saving
Process the raw content object to remove redundant empty blocks before stringifying it. For example, filter out consecutive empty unstyled blocks (the default paragraph type):
function removeExcessiveLineBreaks(rawContent) { return { ...rawContent, blocks: rawContent.blocks.reduce((cleanedBlocks, currentBlock) => { const lastBlock = cleanedBlocks[cleanedBlocks.length - 1]; // Only keep an empty block if the previous block isn't also empty if (currentBlock.type === 'unstyled' && currentBlock.text.trim() === '') { if (!lastBlock || !(lastBlock.type === 'unstyled' && lastBlock.text.trim() === '')) { cleanedBlocks.push(currentBlock); } } else { cleanedBlocks.push(currentBlock); } return cleanedBlocks; }, []) }; } // Usage when saving const rawContent = convertToRaw(myEditorState.getCurrentContent()); const cleanedRawContent = removeExcessiveLineBreaks(rawContent); const serializedContent = JSON.stringify(cleanedRawContent);
Option 2: Restrict input in the editor
Prevent users from adding multiple consecutive line breaks in real-time by listening to the onChange event and modifying the ContentState before it updates the editor:
const handleEditorChange = (newEditorState) => { const currentContent = newEditorState.getCurrentContent(); const blocks = currentContent.getBlocksAsArray(); // Filter out consecutive empty blocks let cleanedBlocks = []; blocks.forEach(block => { const lastBlock = cleanedBlocks[cleanedBlocks.length - 1]; if (block.getType() === 'unstyled' && block.getText().trim() === '') { if (!lastBlock || !(lastBlock.getType() === 'unstyled' && lastBlock.getText().trim() === '')) { cleanedBlocks.push(block); } } else { cleanedBlocks.push(block); } }); // Create a cleaned ContentState and EditorState const cleanedContentState = ContentState.createFromBlockArray(cleanedBlocks); const cleanedEditorState = EditorState.createWithContent(cleanedContentState); // Update your state with the leaner EditorState setMyEditorState(cleanedEditorState); };
This way, you reduce the size at the source, so even the in-memory EditorState stays lean.
内容的提问来源于stack exchange,提问作者Arthur

