点击NextUI Table行激活Modal失败,遇类型错误求助
问题:NextUI Table行点击弹出Modal时出现Symbol转字符串错误
我用NextJS、TypeScript和TailwindCSS开发个人作品集,其中一个页面通过NextUI Table展示读过的书籍及评分,想要实现点击行弹出Modal显示书评的功能,但遇到以下错误:
Uncaught TypeError: Cannot convert a Symbol value to string at $eb2240fc39a57fa5$export$bf788dd355e3a401.getFullNode (import.mjs:219:53) at getFullNode.next (<anonymous>) at eval (import.mjs:282:30) at Generator.next (<anonymous>) at [Symbol.iterator] (import.mjs:303:22) at Generator.next (<anonymous>) at visit (import.mjs:717:22) at new $788781baa30117fa$export$596e1b2e2cf93690 (import.mjs:768:165) at eval (import.mjs:330:16) at updateMemo (react-dom.development.js:12462:5) at Object.useMemo (react-dom.development.js:13396:16) at useMemo (react.development.js:1772:21) at $7613b1592d41b092$export$6cd28814d92fa9c9 (import.mjs:324:65) at $4a0dd036d492cee4$export$907bcc6c48325fd6 (import.mjs:768:96) at useTable (chunk-774VMS2G.mjs:56:84) at eval (chunk-MJZDDVZM.mjs:42:68) at renderWithHooks (react-dom.development.js:11009:18) at updateForwardRef (react-dom.development.js:15665:20) at beginWork$1 (react-dom.development.js:18408:16) at beginWork (react-dom.development.js:26741:14) at performUnitOfWork (react-dom.development.js:25587:12) at workLoopSync (react-dom.development.js:25303:5) at renderRootSync (react-dom.development.js:25258:7) at recoverFromConcurrentError (react-dom.development.js:24475:20) at performConcurrentWorkOnRoot (react-dom.development.js:24420:26) at workLoop (scheduler.development.js:261:34) at flushWork (scheduler.development.js:230:14) at MessagePort.performWorkUntilDeadline (scheduler.development.js:534:21)
当前渲染行及Modal的代码:
{(item) => { return ( <> <TableRow key={item.title} className='hover:bg-sky-100 hover:dark:bg-gray-950 hover:dark:border-black/40 hover:dark:bg-opacity-30' onClick={onOpen} > <TableCell className="" > {item.title} </TableCell> <TableCell className="text-center" > {item.author} </TableCell> <TableCell className="text-center" > {item.date_read ? item.date_read.toLocaleDateString() : 'N/A'} </TableCell> <TableCell className="text-center"> <Rating name="star-rating" value={typeof item.overall_score === 'number' ? item.overall_score : parseFloat(item.overall_score)} precision={.1} readOnly size="large" /> </TableCell> <TableCell className="text-center"> {item.overall_score} </TableCell> </TableRow> <Modal isOpen={isOpen} onOpenChange={onOpenChange}> <ModalContent> {(onClose) => ( <> <ModalHeader className="flex flex-col gap-1">Modal Title</ModalHeader> <ModalBody> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. </p> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. </p> <p> Magna exercitation reprehenderit magna aute tempor cupidatat consequat elit dolor adipisicing. Mollit dolor eiusmod sunt ex incididunt cillum quis. Velit duis sit officia eiusmod Lorem aliqua enim laboris do dolor eiusmod. Et mollit incididunt nisi consectetur esse laborum eiusmod pariatur proident Lorem eiusmod et. Culpa deserunt nostrud ad veniam. </p> </ModalBody> <ModalFooter> <Button color="danger" variant="light" onPress={onClose}> Close </Button> <Button color="primary" onPress={onClose}> Action </Button> </ModalFooter> </> )} </ModalContent> </Modal> </> ) }}
相关版本信息:
- react 18
- next 14.0.4
- nextui-org/react 2.2.9
解决建议
出现这个错误的核心原因是:你在NextUI Table的行渲染函数中返回了TableRow+Modal的组合,而NextUI的Table组件要求每行渲染函数仅返回TableRow元素,额外的Modal会破坏Table内部的DOM结构和状态计算,从而触发Symbol转字符串的错误。
调整方案如下:
- 将Modal移到Table组件外部:只保留一个全局Modal,避免每行都生成一个Modal实例。
- 添加状态存储当前选中的书籍:用状态变量记录点击的书籍数据,在Modal中展示对应内容。
- 修改行点击事件:点击行时更新选中书籍状态并打开Modal。
示例代码调整:
// 在组件顶部添加状态 const [isOpen, setIsOpen] = useState(false); // 替换BookType为你的书籍数据类型 const [selectedBook, setSelectedBook] = useState<BookType | null>(null); // 行点击处理函数 const handleRowClick = (book: BookType) => { setSelectedBook(book); setIsOpen(true); }; // 表格行渲染部分仅返回TableRow {(item) => ( <TableRow key={item.title} className='hover:bg-sky-100 hover:dark:bg-gray-950 hover:dark:border-black/40 hover:dark:bg-opacity-30' onClick={() => handleRowClick(item)} > {/* 表格单元格内容保持不变 */} <TableCell className="" >{item.title}</TableCell> <TableCell className="text-center" >{item.author}</TableCell> <TableCell className="text-center" >{item.date_read ? item.date_read.toLocaleDateString() : 'N/A'}</TableCell> <TableCell className="text-center"> <Rating name="star-rating" value={typeof item.overall_score === 'number' ? item.overall_score : parseFloat(item.overall_score)} precision={.1} readOnly size="large" /> </TableCell> <TableCell className="text-center">{item.overall_score}</TableCell> </TableRow> )} // 在Table组件外部放置Modal <Modal isOpen={isOpen} onOpenChange={setIsOpen}> <ModalContent> {(onClose) => ( <> <ModalHeader className="flex flex-col gap-1">{selectedBook?.title || '书评'}</ModalHeader> <ModalBody> {selectedBook ? ( <div> <p><strong>作者:</strong>{selectedBook.author}</p> <p><strong>阅读日期:</strong>{selectedBook.date_read ? selectedBook.date_read.toLocaleDateString() : 'N/A'}</p> <p><strong>评分:</strong>{selectedBook.overall_score}</p> <div className="mt-4"> {/* 替换为实际的书评内容字段 */} {selectedBook.review || '暂无书评'} </div> </div> ) : ( <p>加载中...</p> )} </ModalBody> <ModalFooter> <Button color="danger" variant="light" onPress={onClose}> 关闭 </Button> </ModalFooter> </> )} </ModalContent> </Modal>
这样调整后,既符合NextUI Table的渲染规范,又能正确实现点击行弹出对应书籍Modal的功能,同时避免了DOM结构冲突导致的错误。
内容的提问来源于stack exchange,提问作者richrosh3
相关产品推荐
相关产品推荐

