How to Integrate Spreadsheet into Existing React Layouts
14 Aug 202624 minutes to read
Overview
The React Spreadsheet component can be embedded into dashboards, admin panels, split‑screen views, tabs, dialogs, collapsible/accordion sections, sidebars, and multi‑column layouts. This guide provides concise layout patterns and minimal code examples to ensure the Spreadsheet renders correctly, resizes properly, and refreshes when hosted inside common layout containers.
How‑To
Use Spreadsheet inside Tab components
The React Spreadsheet component is fully supported within Syncfusion Tab component. You can safely place and render the Spreadsheet inside a Tab item.
The following sample shows how to render the Spreadsheet inside the Tab component.
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
function App() {
const SpreadsheetTabContent = () => {
return (
<div className="spreadsheet-pane">
<div>
<SpreadsheetComponent height="100%" width="100%" />
</div>
</div>
);
};
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet in tab</h3>
</header>
<div className="tab-host">
<TabComponent height="100%">
<TabItemsDirective>
<TabItemDirective
header=
content={() => (
<div className="panel">
<h4>Overview</h4>
<p>Put general dashboard content here.</p>
</div>
)}
/>
<TabItemDirective
header=
content={SpreadsheetTabContent}
/>
<TabItemDirective
header=
content={() => (
<div className="panel">
<h4>Settings</h4>
<p>Any settings or forms can go here.</p>
</div>
)}
/>
</TabItemsDirective>
</TabComponent>
</div>
</div>
);
};
export default App;
const root = createRoot(document.getElementById('root'));
root.render(<App />);import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { TabComponent, TabItemsDirective, TabItemDirective } from '@syncfusion/ej2-react-navigations';
function App(): React.ReactElement {
const SpreadsheetTabContent: any = () => {
return (
<div className="spreadsheet-pane">
<div>
<SpreadsheetComponent height="100%" width="100%" />
</div>
</div>
);
};
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet in tab</h3>
</header>
<div className="tab-host">
<TabComponent height="100%">
<TabItemsDirective>
<TabItemDirective
header=
content={() => (
<div className="panel">
<h4>Overview</h4>
<p>Put general dashboard content here.</p>
</div>
)}
/>
<TabItemDirective
header=
content={SpreadsheetTabContent}
/>
<TabItemDirective
header=
content={() => (
<div className="panel">
<h4>Settings</h4>
<p>Any settings or forms can go here.</p>
</div>
)}
/>
</TabItemsDirective>
</TabComponent>
</div>
</div>
);
};
export default App;
const root = createRoot(document.getElementById('root')!);
root.render(<App />);Use Spreadsheet inside Dialog
If the Spreadsheet is placed inside a dialog (for example, a Syncfusion Dialog), render or initialize the Spreadsheet only within the dialog’s open event. The parent container must be visible in the DOM for the Spreadsheet to correctly measure and compute its layout.
And if the Spreadsheet is rendered while the dialog container is hidden and the container is made visible later, the Spreadsheet’s layout may not calculated properly. In such cases, invoke the resize method in the dialog’s open event to re-render the Spreadsheet layout based on the currently visible parent container.
The following sample shows how to render the Spreadsheet inside the Dialog component.
import * as React from 'react';
import { useRef, useCallback } from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { DialogComponent } from '@syncfusion/ej2-react-popups';
function App() {
const dialogRef = useRef(null);
const spreadsheetRef = useRef(null);
const openDialog = () => {
dialogRef.current.show();
};
const closeDialog = () => {
dialogRef.current.hide();
};
const onDialogOpen = useCallback(() => {
setTimeout(() => {
// Use resize method to recompute layout after panel becomes visible
spreadsheetRef.current.resize();
}, 0);
}, []);
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet inside Dialog</h3>
<div style=>
<button onClick={openDialog}>Open Spreadsheet</button>
</div>
</header>
<DialogComponent
ref={(dlg) => (dialogRef.current = dlg)}
isModal={true}
visible={false}
header="Spreadsheet"
showCloseIcon={true}
minHeight="80vh"
width="80vw"
height="80vh"
allowDragging={true}
closeOnEscape={true}
target={document.body}
overlayClick={closeDialog}
open={onDialogOpen}
>
<SpreadsheetComponent height="100%" width="100%" />
</DialogComponent>
</div>
);
}
export default App;
const root = createRoot(document.getElementById('root'));
root.render(<App />);import * as React from 'react';
import { useRef, useCallback } from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { DialogComponent } from '@syncfusion/ej2-react-popups';
function App(): React.ReactElement {
const dialogRef = useRef<DialogComponent | null>(null);
const spreadsheetRef = useRef<SpreadsheetComponent | null>(null);
const openDialog = () => {
dialogRef.current.show();
};
const closeDialog = () => {
dialogRef.current.hide();
};
const onDialogOpen = useCallback(() => {
setTimeout(() => {
// Use resize method to recompute layout after panel becomes visible
spreadsheetRef.current.resize();
}, 0);
}, []);
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet inside Dialog</h3>
<div style=>
<button onClick={openDialog}>Open Spreadsheet</button>
</div>
</header>
<DialogComponent
ref={(dlg: any) => (dialogRef.current = dlg)}
isModal={true}
visible={false}
header="Spreadsheet"
showCloseIcon={true}
minHeight="80vh"
width="80vw"
height="80vh"
allowDragging={true}
closeOnEscape={true}
target={document.body as any}
overlayClick={closeDialog}
open={onDialogOpen}
>
<SpreadsheetComponent height="100%" width="100%" />
</DialogComponent>
</div>
);
}
export default App;
const root = createRoot(document.getElementById('root')!);
root.render(<App />);Use Spreadsheet inside collapsible sections
When placing the Spreadsheet inside an accordion or any collapsible container (for example, within an AccordionItem), it is important to ensure that the Spreadsheet is rendered only when the corresponding section is visible. The Spreadsheet relies on the visibility of its parent container in the DOM to accurately measure dimensions and compute its layout.
If the accordion item is initialized while it is in a collapsed (hidden) state, the Spreadsheet will not be able to calculate its layout correctly, which may result where the Spreadsheet will not be displayed fully. To avoid this, you can either:
- Render or initialize the Spreadsheet only when the accordion item becomes active (expanded), or
- If the Spreadsheet must be rendered while the accordion item is hidden, explicitly trigger a Spreadsheet’s resize method in the accordion’s expanded event to re-render the Spreadsheet layout based on the current parent container.
The following sample shows how to render the Spreadsheet inside the Accordion.
import * as React from 'react';
import { useCallback, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { AccordionComponent, AccordionItemsDirective, AccordionItemDirective } from '@syncfusion/ej2-react-navigations';
function App() {
const spreadsheetRef = useRef(null);
const onExpanded = useCallback((args) => {
setTimeout(() => {
// Use resize method to recompute layout after panel becomes visible
spreadsheetRef.current.resize();
}, 0);
}, []);
const spreadsheetContent = () => (
<div className="sheet-pane">
<SpreadsheetComponent
ref={(spreadsheet) => (spreadsheetRef.current = spreadsheet)}
id="spreadsheetInAccordion"
height="100%"
width="100%"
/>
</div>
);
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet inside an Accordion</h3>
</header>
<main className="content">
<AccordionComponent
expandMode="Single"
expanding={onExpanded}
expanded={onExpanded}
>
<AccordionItemsDirective>
<AccordionItemDirective
header="Overview"
content={() => (
<div className="panel">
<h4>Overview</h4>
<p>Place any introductory content here.</p>
</div>
)}
/>
<AccordionItemDirective
header="Spreadsheet"
expanded={true}
content={spreadsheetContent}
/>
<AccordionItemDirective
header="Settings"
content={() => (
<div className="panel">
<h4>Settings</h4>
<p>Your forms and other controls here.</p>
</div>
)}
/>
</AccordionItemsDirective>
</AccordionComponent>
</main>
</div>
);
}
export default App;
const root = createRoot(document.getElementById('root'));
root.render(<App />);import * as React from 'react';
import { useCallback, useRef } from 'react';
import { createRoot } from 'react-dom/client';
import { SpreadsheetComponent } from '@syncfusion/ej2-react-spreadsheet';
import { AccordionComponent, AccordionItemsDirective, AccordionItemDirective, ExpandEventArgs } from '@syncfusion/ej2-react-navigations';
function App(): React.ReactElement {
const spreadsheetRef = useRef<SpreadsheetComponent | null>(null);
const onExpanded = useCallback((args: ExpandEventArgs) => {
setTimeout(() => {
// Use resize method to recompute layout after panel becomes visible
spreadsheetRef.current.resize();
}, 0);
}, []);
const spreadsheetContent = () => (
<div className="sheet-pane">
<SpreadsheetComponent
ref={(spreadsheet: any) => (spreadsheetRef.current = spreadsheet)}
id="spreadsheetInAccordion"
height="100%"
width="100%"
/>
</div>
);
return (
<div className="page">
<header className="header">
<h3 style=>Spreadsheet inside an Accordion</h3>
</header>
<main className="content">
<AccordionComponent
expandMode="Single"
expanding={onExpanded}
expanded={onExpanded}
>
<AccordionItemsDirective>
<AccordionItemDirective
header="Overview"
content={() => (
<div className="panel">
<h4>Overview</h4>
<p>Place any introductory content here.</p>
</div>
)}
/>
<AccordionItemDirective
header="Spreadsheet"
expanded={true}
content={spreadsheetContent}
/>
<AccordionItemDirective
header="Settings"
content={() => (
<div className="panel">
<h4>Settings</h4>
<p>Your forms and other controls here.</p>
</div>
)}
/>
</AccordionItemsDirective>
</AccordionComponent>
</main>
</div>
);
}
export default App;
const root = createRoot(document.getElementById('root')!);
root.render(<App />);Note: Mount the Spreadsheet component only when the corresponding pane becomes visible. If the Spreadsheet must be mounted while hidden, call its resize method after the pane is shown so that the layout is recalculated correctly.
When to use these patterns
- Use Dialogs for temporary or isolated spreadsheet previews.
- Use Tabs/Accordion patterns for multi-pane UIs — ensure a resize is triggered when a pane becomes active.
- Avoid placing the Spreadsheet in invisible containers without a resize strategy; otherwise the Spreadsheet layout will not calculated correctly.