【发布时间】:2021-01-11 03:12:18
【问题描述】:
我被这个问题困扰了很多天。我正在使用Next.js 并且有 3 页。
- pages/index.js
- pages/categories.js
- 页面/类别/[slug].js
categories/[slug].js 使用Next.js 获取方法名称getServerSideProps,该方法在每个请求上运行并用于在运行时构建动态页面。 categories/[slug].js 在页面上呈现动态内容,动态内容来自 CMS,作为 API 端点的响应。动态内容只不过是一个包含带有<script /> 元素的HTML 的字符串。
注意:要从 CMS 获取内容,我们必须发送带有 CMS 凭据的 POST 请求,例如用户名、密码和内容的页面 slug。我正在使用axios 库发送一个post 请求,方法在post.js 文件中。
post.js:
import axios from 'axios';
const postCMS = async (slug) => {
const url = `${process.env.CMS_API_URL}/render-page/`;
let pageSlug = slug;
// If the pageSlug is not start with `/`, then create the slug with `/`
if (!pageSlug.startsWith('/')) {
pageSlug = `/${pageSlug}`;
}
const head = {
Accept: 'application/json',
'Content-Type': 'application/json'
};
const data = JSON.stringify({
username: process.env.CMS_API_USERNAME,
password: process.env.CMS_API_PASSWORD,
slug: pageSlug
});
try {
const response = await axios.post(url, data, {
headers: head
});
return response.data;
} catch (e) {
return e;
}
};
export default postCMS;
但是对于categories/[slug].js 页面上的渲染内容,我使用Reactjs 道具名称dangerouslySetInnerHTML 来渲染所有HTML,其中还包含JSON 字符串中的<script /> 元素。
页面/类别/[slug].js:
<div dangerouslySetInnerHTML={{ __html: result.html }} />
根据每个 slug,内容加载良好。但是当我导航到该类别页面时,即pages/categories/index.js。
<Link href="/categories/[slug]" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
它有一个<Link /> 元素,当我点击它时。
动态内容加载正常,但动态内容包含无法正常工作的 accordion 和 slider 元素。我认为这些元素中的<script /> 不起作用。但是当我刷新页面时,它们工作正常。看这个。
当我设置这样的链接时,它们也可以正常工作。
<Link href="/categories/online-cloud-storage" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
但是像上面的方法设置链接后,点击导致页面硬重载。但我不想要这个。一切都应该工作。当用户点击类别链接时。
有没有办法解决这个问题?
为什么当您从categories/index.js 页面点击时内容元素不起作用?
代码:
pages/index.js:
import React from 'react';
import Link from 'next/link';
const IndexPage = () => {
return (
<div>
<Link href="/categories">
<a>Categories</a>
</Link>
</div>
);
};
export default IndexPage;
页面/类别/index.js:
import React from 'react';
import Link from 'next/link';
const Categories = () => {
return (
<div>
<Link href="/categories/[slug]" as="/categories/online-cloud-storage">
<a>Online Cloud Storage</a>
</Link>
</div>
);
};
export default Categories;
页面/类别/[slug].js:
import React from 'react';
import Head from 'next/head';
import postCMS from '../../post';
const CategoryPage = ({ result }) => {
return (
<>
<Head>
{result && <link href={result.assets.stylesheets} rel="stylesheet" />}
</Head>
<div>
<h1>Category page CMS Content</h1>
<div dangerouslySetInnerHTML={{ __html: result.html }} />
</div>
</>
);
};
export const getServerSideProps = async (context) => {
const categorySlug = context.query.slug;
const result = await postCMS(categorySlug);
return {
props: {
result
}
};
};
export default CategoryPage;
【问题讨论】:
-
点击手风琴时控制台是否有任何错误? (在不工作的版本中)
-
您能否提供 CMS 网址?如果可以,能否提供用户名和密码?
-
@dna 不,没有任何控制台错误。我认为
dangerouslySetInnerHTML={{ __html: result.html }}没有运行 javascript<script />和<script />元素总是在客户端运行。 -
@TopTalent 这是机密凭据。
-
我认为stackoverflow question 会对您有所帮助。实际上,script 标签在 dangerouslySetInnerHTML 中不起作用,所以需要在组件挂载后运行脚本。