Overview
The useBlockData hook provides a convenient way to access block data for a specific block ID. It’s a shorthand for accessing editor.children[blockId].
Usage
import { useBlockData } from '@yoopta/editor';
function BlockInfo({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
if (!block) return null;
return (
<div>
<p>Type: {block.type}</p>
<p>Order: {block.meta.order}</p>
<p>Depth: {block.meta.depth}</p>
</div>
);
}
Signature
function useBlockData(blockId: string): YooptaBlockData | undefined
Parameters
The unique identifier of the block to retrieve
Returns
YooptaBlockData | undefined - The block data object, or undefined if not found
Block Data Structure
The returned block data has the following structure:
type YooptaBlockData = {
id: string; // Unique block identifier
type: string; // Block type (e.g., "Paragraph", "HeadingOne")
value: SlateElement[]; // Slate element array
meta: {
order: number; // Position in document
depth: number; // Nesting level (0 = root)
align?: 'left' | 'center' | 'right'; // Text alignment
};
}
Examples
function BlockMetadata({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
if (!block) {
return <div>Block not found</div>;
}
return (
<div>
<h3>Block Information</h3>
<ul>
<li>ID: {block.id}</li>
<li>Type: {block.type}</li>
<li>Position: {block.meta.order}</li>
<li>Depth: {block.meta.depth}</li>
{block.meta.align && <li>Alignment: {block.meta.align}</li>}
</ul>
</div>
);
}
Conditional Rendering Based on Block Type
function BlockTypeIndicator({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
if (!block) return null;
const isHeading = block.type.startsWith('Heading');
const isParagraph = block.type === 'Paragraph';
return (
<div>
{isHeading && <span>📰 Heading</span>}
{isParagraph && <span>📝 Paragraph</span>}
</div>
);
}
Access Block Content
function BlockContentLength({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
if (!block) return null;
const element = block.value[0];
const textContent = element?.children
?.map(child => 'text' in child ? child.text : '')
.join('');
return (
<div>
Content length: {textContent?.length || 0} characters
</div>
);
}
Check Block Nesting
function BlockNestingIndicator({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
if (!block) return null;
const nestingLevel = block.meta.depth;
const isNested = nestingLevel > 0;
return (
<div style={{ marginLeft: `${nestingLevel * 20}px` }}>
{isNested && `↳ Nested (Level ${nestingLevel})`}
{!isNested && 'Root level'}
</div>
);
}
Use Cases
- Custom UI Components: Display block metadata or custom controls
- Conditional Rendering: Show/hide UI based on block type or state
- Block Analytics: Track block usage and patterns
- Custom Toolbars: Build block-specific toolbars
- Validation: Check block properties before operations
This hook accesses the editor context, so it will re-render when the editor state changes. For performance-critical components, consider:
- Memoizing derived values with
useMemo
- Using
React.memo to prevent unnecessary re-renders
- Extracting only the data you need
function OptimizedBlockInfo({ blockId }: { blockId: string }) {
const block = useBlockData(blockId);
// Memoize derived values
const blockType = useMemo(() => block?.type, [block?.type]);
const blockOrder = useMemo(() => block?.meta.order, [block?.meta.order]);
return (
<div>
<span>Type: {blockType}</span>
<span>Order: {blockOrder}</span>
</div>
);
}
See Also