如何在Next.js应用中渲染不可修改的原生JS与HTML代码?
问题描述
我有一段原生JavaScript与HTML代码,无法将其修改为JSX格式,希望在Next.js应用中进行渲染。尝试使用React Helmet直接嵌入代码但未成功渲染,请问是否有其他可行方案?
原生JavaScript与HTML代码
<!DOCTYPE html> <html> <head> <title>JSON to Table</title> </head> <body> <h1>JSON Data</h1> <table id="dataTable"> <thead> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> </thead> <tbody> </tbody> </table> <script> // Sample JSON data const data = [ { name: "John Doe", age: 35, city: "New York" }, { name: "Jane Smith", age: 28, city: "Los Angeles" }, { name: "Bob Johnson", age: 42, city: "Chicago" }, { name: "Sarah Lee", age: 31, city: "Miami" } ]; // Get the table body element const tableBody = document.querySelector('#dataTable tbody'); // Loop through the data and create table rows data.forEach(item => { const row = document.createElement('tr'); const nameCell = document.createElement('td'); nameCell.textContent = item.name; row.appendChild(nameCell); const ageCell = document.createElement('td'); ageCell.textContent = item.age; row.appendChild(ageCell); const cityCell = document.createElement('td'); cityCell.textContent = item.city; row.appendChild(cityCell); tableBody.appendChild(row); }); </script> </body> </html>
尝试的Next.js代码(未成功)
"use client" import {Helmet} from "react-helmet"; const Page = () => { return ( <> <div className="w-screen h-screen flex items-start justify-start overflow-hidden"> <Helmet> <title>Nested Title</title> <meta name="description" content="Nested component"/> <html> {`<!DOCTYPE html> <html> <head> <title>JSON to Table</title> </head> <body> <h1>JSON Data</h1> <table id="dataTable"> <thead> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> </thead> <tbody> </tbody> </table> <script> // Sample JSON data const data = [ { name: "John Doe", age: 35, city: "New York" }, { name: "Jane Smith", age: 28, city: "Los Angeles" }, { name: "Bob Johnson", age: 42, city: "Chicago" }, { name: "Sarah Lee", age: 31, city: "Miami" } ]; // Get the table body element const tableBody = document.querySelector('#dataTable tbody'); // Loop through the data and create table rows data.forEach(item => { const row = document.createElement('tr'); const nameCell = document.createElement('td'); nameCell.textContent = item.name; row.appendChild(nameCell); const ageCell = document.createElement('td'); ageCell.textContent = item.age; row.appendChild(ageCell); const cityCell = document.createElement('td'); cityCell.textContent = item.city; row.appendChild(cityCell); tableBody.appendChild(row); }); </script> </body> </html>`} </html> </Helmet> </div> </> ); } export default Page;
可行解决方案
方案1:用JSX直接重写(最符合Next.js规范)
这个案例逻辑简单,直接用React的声明式渲染更适配Next.js生态,避免手动DOM操作的问题:
"use client" const Page = () => { const data = [ { name: "John Doe", age: 35, city: "New York" }, { name: "Jane Smith", age: 28, city: "Los Angeles" }, { name: "Bob Johnson", age: 42, city: "Chicago" }, { name: "Sarah Lee", age: 31, city: "Miami" } ]; return ( <div className="w-screen h-screen flex items-start justify-start overflow-hidden p-4"> <h1>JSON Data</h1> <table id="dataTable" border="1" cellPadding="8"> <thead> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> </thead> <tbody> {data.map((item, index) => ( <tr key={index}> <td>{item.name}</td> <td>{item.age}</td> <td>{item.city}</td> </tr> ))} </tbody> </table> </div> ); }; export default Page;
方案2:使用dangerouslySetInnerHTML嵌入完整HTML(适合完全保留原生代码的场景)
注意:此方法存在XSS风险,仅在完全信任嵌入内容时使用。需要转义脚本标签的闭合符,避免提前终止字符串:
"use client" const Page = () => { const htmlContent = ` <h1>JSON Data</h1> <table id="dataTable" border="1" cellPadding="8"> <thead> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> </thead> <tbody> </tbody> </table> <script> const data = [ { name: "John Doe", age: 35, city: "New York" }, { name: "Jane Smith", age: 28, city: "Los Angeles" }, { name: "Bob Johnson", age: 42, city: "Chicago" }, { name: "Sarah Lee", age: 31, city: "Miami" } ]; const tableBody = document.querySelector('#dataTable tbody'); data.forEach(item => { const row = document.createElement('tr'); const nameCell = document.createElement('td'); nameCell.textContent = item.name; row.appendChild(nameCell); const ageCell = document.createElement('td'); ageCell.textContent = item.age; row.appendChild(ageCell); const cityCell = document.createElement('td'); cityCell.textContent = item.city; row.appendChild(cityCell); tableBody.appendChild(row); }); <\/script> `; return ( <div className="w-screen h-screen flex items-start justify-start overflow-hidden p-4" dangerouslySetInnerHTML={{ __html: htmlContent }} /> ); }; export default Page;
方案3:在useEffect中执行原生JS逻辑(保留原生DOM操作逻辑)
用JSX构建HTML结构,在组件挂载后执行原生DOM操作逻辑:
"use client" import { useEffect } from 'react'; const Page = () => { useEffect(() => { const data = [ { name: "John Doe", age: 35, city: "New York" }, { name: "Jane Smith", age: 28, city: "Los Angeles" }, { name: "Bob Johnson", age: 42, city: "Chicago" }, { name: "Sarah Lee", age: 31, city: "Miami" } ]; const tableBody = document.querySelector('#dataTable tbody'); // 清空内容避免重复渲染 tableBody.innerHTML = ''; data.forEach(item => { const row = document.createElement('tr'); const nameCell = document.createElement('td'); nameCell.textContent = item.name; row.appendChild(nameCell); const ageCell = document.createElement('td'); ageCell.textContent = item.age; row.appendChild(ageCell); const cityCell = document.createElement('td'); cityCell.textContent = item.city; row.appendChild(cityCell); tableBody.appendChild(row); }); }, []); // 空依赖确保只执行一次 return ( <div className="w-screen h-screen flex items-start justify-start overflow-hidden p-4"> <h1>JSON Data</h1> <table id="dataTable" border="1" cellPadding="8"> <thead> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> </thead> <tbody> </tbody> </table> </div> ); }; export default Page;
内容的提问来源于stack exchange,提问作者user3322378
相关产品推荐
相关产品推荐

