You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:27:33