UNPKG

nextjs-reusable-table

Version:

A production-ready, highly customizable and reusable table component for Next.js applications. Features include sorting, pagination, search, dark mode, TypeScript support, and zero dependencies.

660 lines (504 loc) 13.8 kB
# 🔧 Troubleshooting Guide Common issues and solutions when using nextjs-reusable-table. ## Table of Contents - [Installation Issues](#installation-issues) - [Styling Problems](#styling-problems) - [TypeScript Errors](#typescript-errors) - [Performance Issues](#performance-issues) - [Functionality Problems](#functionality-problems) - [SSR/Hydration Issues](#ssrhydration-issues) - [Browser Compatibility](#browser-compatibility) ## Installation Issues ### Package Not Found **Problem**: `npm ERR! 404 Not Found - GET https://registry.npmjs.org/nextjs-reusable-table` **Solution**: ```bash # Make sure you're installing the correct package name npm install nextjs-reusable-table@latest # Clear npm cache if needed npm cache clean --force # Try with different registry npm install nextjs-reusable-table --registry https://registry.npmjs.org/ ``` ### Peer Dependency Warnings **Problem**: Warnings about unmet peer dependencies **Solution**: ```bash # Install all required peer dependencies npm install react@^16.8.0 react-dom@^16.8.0 next@^12.0.0 # For TypeScript projects npm install -D @types/react @types/react-dom ``` ### CSS Not Loading **Problem**: Table appears unstyled **Solutions**: 1. Import the CSS file: ```typescript import "nextjs-reusable-table/dist/index.css"; ``` 2. Add to your global CSS (in `_app.tsx` or `layout.tsx`): ```css @import "nextjs-reusable-table/dist/index.css"; ``` 3. Configure your bundler to handle CSS imports from node_modules. ## Styling Problems ### Tailwind Classes Not Working **Problem**: Custom classes not applying or being overridden **Solutions**: 1. **Check Tailwind configuration**: ```javascript // tailwind.config.js module.exports = { content: [ "./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", "./node_modules/nextjs-reusable-table/**/*.{js,jsx,ts,tsx}", // Add this ], // ... rest of config } ``` 2. **Use `!important` for overrides**: ```typescript const customStyles = { table: "!bg-red-500", // Force override th: "!text-white !font-bold", }; ``` 3. **Disable default styles completely**: ```typescript <TableComponent disableDefaultStyles={true} customClassNames={yourCompleteCustomStyles} // ... other props /> ``` ### Dark Mode Not Working **Problem**: Dark mode styles not applying **Solutions**: 1. **Check system preferences**: ```typescript // Force dark mode for testing <TableComponent enableDarkMode={true} customClassNames={{ table: "dark:bg-gray-800", // Ensure dark: variants are included }} // ... other props /> ``` 2. **Configure Tailwind for dark mode**: ```javascript // tailwind.config.js module.exports = { darkMode: 'media', // or 'class' // ... rest of config } ``` ### Responsive Issues **Problem**: Table not responsive on mobile **Solutions**: 1. **Enable horizontal scroll**: ```css .table-container { overflow-x: auto; } ``` 2. **Use responsive breakpoints**: ```typescript const responsiveStyles = { th: "px-2 py-2 sm:px-4 sm:py-4 text-xs sm:text-sm", td: "px-2 py-2 sm:px-4 sm:py-4 text-xs sm:text-sm", }; ``` ## TypeScript Errors ### Generic Type Issues **Problem**: `Type 'string' is not assignable to type 'keyof T'` **Solution**: ```typescript // ❌ Wrong const props = ["id", "name", "email"]; // string[] // ✅ Correct const props = ["id", "name", "email"] as const; // readonly ["id", "name", "email"] // ✅ Or with proper typing interface User { id: number; name: string; email: string; } const props: (keyof User)[] = ["id", "name", "email"]; ``` ### Missing Type Definitions **Problem**: `Cannot find module 'nextjs-reusable-table' or its corresponding type declarations` **Solution**: ```typescript // Create a type declaration file: types/nextjs-reusable-table.d.ts declare module 'nextjs-reusable-table' { import { ReactNode } from 'react'; export interface TableProps<T> { columns: string[]; data: T[]; props: ReadonlyArray<keyof T>; // ... add other props you're using } export function TableComponent<T>(props: TableProps<T>): ReactNode; } ``` ### Strict Mode Errors **Problem**: TypeScript strict mode complaints **Solutions**: 1. **Proper null checking**: ```typescript // ❌ Wrong const formatValue = (value: string, prop: string, item: T) => { return item.someProperty.toString(); // might be undefined }; // ✅ Correct const formatValue = (value: string, prop: string, item: T) => { return item.someProperty?.toString() ?? 'N/A'; }; ``` 2. **Proper event typing**: ```typescript // ❌ Wrong const handleClick = (e: any) => { /* ... */ }; // ✅ Correct const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { /* ... */ }; ``` ## Performance Issues ### Slow Rendering with Large Datasets **Problem**: Table is slow with 1000+ rows **Solutions**: 1. **Enable pagination**: ```typescript <TableComponent enablePagination itemsPerPage={50} // Reasonable page size // ... other props /> ``` 2. **Implement virtualization** (custom solution): ```typescript import { FixedSizeList as List } from 'react-window'; const VirtualizedTable = ({ data }) => ( <List height={600} itemCount={data.length} itemSize={60} itemData={data} > {({ index, data, style }) => ( <div style={style}> <TableComponent data={[data[index]]} // ... other props /> </div> )} </List> ); ``` 3. **Memoize heavy computations**: ```typescript const formatValue = useCallback((value: string, prop: string, item: T) => { // Heavy computation here return expensiveFormatting(value); }, []); const memoizedData = useMemo(() => { return data.map(item => ({ ...item, computedField: heavyComputation(item) })); }, [data]); ``` ### Memory Leaks **Problem**: Component not cleaning up properly **Solutions**: 1. **Cleanup event listeners**: ```typescript useEffect(() => { const handleResize = () => { // Handle resize }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); ``` 2. **Cancel ongoing operations**: ```typescript useEffect(() => { const controller = new AbortController(); fetchData(controller.signal).then(setData); return () => controller.abort(); }, []); ``` ## Functionality Problems ### Search Not Working **Problem**: Search functionality not filtering data **Solutions**: 1. **Check search value prop**: ```typescript // ❌ Wrong - search value not passed <TableComponent data={data} /* missing searchValue */ /> // ✅ Correct const [search, setSearch] = useState(""); <TableComponent data={data} searchValue={search} // ... other props /> ``` 2. **Case sensitivity issues**: ```typescript // The component does case-insensitive search by default // If you need custom search, filter data yourself: const filteredData = useMemo(() => { if (!searchTerm) return data; return data.filter(item => Object.values(item).some(value => String(value).toLowerCase().includes(searchTerm.toLowerCase()) ) ); }, [data, searchTerm]); ``` ### Pagination Not Working **Problem**: Pagination controls not appearing or not working **Solutions**: 1. **Check required props**: ```typescript // ❌ Missing required props <TableComponent enablePagination /> // ✅ All required props provided const [page, setPage] = useState(1); <TableComponent enablePagination page={page} setPage={setPage} itemsPerPage={10} // ... other props /> ``` 2. **Page state issues**: ```typescript // ✅ Handle page bounds const safeSetPage = (newPage: number) => { const maxPage = Math.ceil(data.length / itemsPerPage); setPage(Math.max(1, Math.min(newPage, maxPage))); }; ``` ### Actions Not Triggering **Problem**: Action dropdown not working or functions not called **Solutions**: 1. **Check props matching**: ```typescript // ❌ Arrays don't match <TableComponent actions={true} actionTexts={["Edit", "Delete"]} actionFunctions={[editFn]} // Missing delete function /> // ✅ Arrays match <TableComponent actions={true} actionTexts={["Edit", "Delete"]} actionFunctions={[editFn, deleteFn]} // Both functions provided /> ``` 2. **Function not defined**: ```typescript // ❌ Functions not properly defined const actionFunctions = [undefined, deleteFn]; // undefined function // ✅ All functions defined const editFn = useCallback((item: T) => { console.log('Edit:', item); }, []); const deleteFn = useCallback((item: T) => { console.log('Delete:', item); }, []); const actionFunctions = [editFn, deleteFn]; ``` ### Sorting Not Working **Problem**: Column sorting not functioning **Solutions**: 1. **Check sortable props**: ```typescript // ❌ sortableProps not defined <TableComponent onSort={handleSort} /> // ✅ sortableProps defined <TableComponent sortableProps={["name", "email", "date"]} onSort={handleSort} /> ``` 2. **Implement sort handler**: ```typescript const [sortConfig, setSortConfig] = useState<{ prop: keyof T; order: 'asc' | 'desc'; } | null>(null); const handleSort = (prop: keyof T) => { setSortConfig(prev => ({ prop, order: prev?.prop === prop && prev.order === 'asc' ? 'desc' : 'asc' })); }; const sortedData = useMemo(() => { if (!sortConfig) return data; return [...data].sort((a, b) => { const aVal = a[sortConfig.prop]; const bVal = b[sortConfig.prop]; if (aVal < bVal) return sortConfig.order === 'asc' ? -1 : 1; if (aVal > bVal) return sortConfig.order === 'asc' ? 1 : -1; return 0; }); }, [data, sortConfig]); ``` ## SSR/Hydration Issues ### Hydration Mismatch **Problem**: `Warning: Text content did not match. Server: "..." Client: "..."` **Solutions**: 1. **Use dynamic imports**: ```typescript import dynamic from 'next/dynamic'; const TableComponent = dynamic( () => import('nextjs-reusable-table').then(mod => mod.TableComponent), { ssr: false } ); ``` 2. **Handle client-only features**: ```typescript import { useState, useEffect } from 'react'; const ClientOnlyTable = ({ data }) => { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); if (!mounted) return <div>Loading...</div>; return <TableComponent data={data} />; }; ``` 3. **Suppress hydration warnings** (use sparingly): ```typescript <div suppressHydrationWarning> <TableComponent data={data} /> </div> ``` ### Dark Mode SSR Issues **Problem**: Dark mode flashing or not matching server/client **Solutions**: 1. **Use next-themes**: ```typescript // _app.tsx import { ThemeProvider } from 'next-themes'; export default function App({ Component, pageProps }) { return ( <ThemeProvider attribute="class"> <Component {...pageProps} /> </ThemeProvider> ); } ``` 2. **Manual theme handling**: ```typescript const [theme, setTheme] = useState<'light' | 'dark'>('light'); useEffect(() => { const savedTheme = localStorage.getItem('theme') as 'light' | 'dark'; if (savedTheme) { setTheme(savedTheme); } else { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; setTheme(prefersDark ? 'dark' : 'light'); } }, []); ``` ## Browser Compatibility ### IE11 Support **Problem**: Not working in Internet Explorer 11 **Solution**: IE11 is not supported. Use modern browsers or: ```javascript // Add polyfills for IE11 if absolutely necessary import 'core-js/stable'; import 'regenerator-runtime/runtime'; ``` ### Safari Issues **Problem**: Styling issues in Safari **Solutions**: 1. **Add webkit prefixes**: ```css .table-container { -webkit-overflow-scrolling: touch; } ``` 2. **Safari-specific styles**: ```typescript const safariStyles = { table: "w-full [-webkit-transform:translateZ(0)]", // Force hardware acceleration }; ``` ### Mobile Safari **Problem**: Touch interactions not working properly **Solution**: ```css button, [role="button"] { -webkit-tap-highlight-color: transparent; touch-action: manipulation; } ``` ## Getting Help ### Debug Information When reporting issues, include: 1. **Package version**: ```bash npm list nextjs-reusable-table ``` 2. **Environment info**: - Next.js version - React version - TypeScript version - Browser and version - Operating system 3. **Minimal reproduction**: ```typescript // Create a minimal example that reproduces the issue import { TableComponent } from "nextjs-reusable-table"; const data = [{ id: 1, name: "Test" }]; export default function MinimalExample() { return ( <TableComponent columns={["ID", "Name"]} data={data} props={["id", "name"]} /> ); } ``` ### Community Resources - **GitHub Issues**: [Report bugs or request features](https://github.com/ninsau/nextjs-reusable-table/issues) - **Discussions**: [Community Q&A](https://github.com/ninsau/nextjs-reusable-table/discussions) - **Examples Repository**: [Live examples and demos](https://github.com/ninsau/nextjs-reusable-table-examples) ### Performance Profiling Use React DevTools Profiler to identify performance bottlenecks: 1. Install React DevTools browser extension 2. Open DevTools → Profiler tab 3. Click "Start profiling" 4. Interact with your table 5. Stop profiling and analyze the flame graph Look for: - Components rendering too frequently - Expensive operations in render cycles - Memory leaks in the profiler ### Enable Debug Mode For development debugging: ```typescript // Add to your component for detailed logging const DebugTable = ({ data }) => { useEffect(() => { console.log('TableComponent data updated:', data.length, 'items'); }, [data]); return ( <TableComponent data={data} // ... other props /> ); }; ```