据我从SO question所了解的,我可以使用next / head将脚本标签嵌入React / Next JS应用程序的组件中。所以,我这样处理:
import React, { Component } from "react";
...
import Head from "next/head";
export const Lead = props => {
return (
...
<Head>
<script
class="3758abc"
type="text/javascript"
src="https://cdn2.fake.com/Scripts/embed-button.min.js"
data-encoded="1234sdkljfeiASD9A"
></script>
</Head>
...
);
};
很遗憾,没有任何显示。我不知道我是否在这里缺少明显的东西... 我正在使用Next 9.1.7。
我的_app.js看起来像这样:
import App, { Container } from "next/app";
import Page from "../components/Page";
import { ApolloProvider } from "react-apollo";
import withData from "../lib/withData";
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
// this exposes the query to the user
pageProps.query = ctx.query;
return { pageProps };
}
render() {
const { Component, apollo, pageProps } = this.props;
return (
// <Container>
<ApolloProvider client={apollo}>
<Page>
<Component {...pageProps} />
</Page>
</ApolloProvider>
// </Container>
);
}
}
export default withData(MyApp);
我的_document看起来像这样:
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static getInitialProps = async ctx => {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
};
} finally {
sheet.seal();
}
};
}
答案 0 :(得分:0)
在您的
async addExpense(req, res){
addOne(req, res, 'Expense')
}
async addPaymentMethod(req, res){
addOne(req, res, 'Payment method')
}
async function addOne(req, res, table) {
if(!req.body.name){
return res.status(400).send({message: 'Expense cannot be added. Name is missing'})
}
try{
switch (table) {
case 'Expense':
await addExpensesQuery(req)
break;
case 'Payment method':
await addPaymentQuery(req)
break;
default:
throw new Error('Unsupported operation')
}
return res.status(200).json({message: `${table} has been successfully added`})
}catch(err){
return res.status(400).send({message: err})
}
}
function addExpensesQuery (req) {
const addExpense ='INSERT INTO budget.expenses_category_assigned_to_user VALUES(DEFAULT, $1, $2)'
const queryValues = [
req.user.id,
req.body.name
]
return db.query(addExpense, queryValues)
}
function addPaymentQuery (req) {
const addQuery = 'INSERT INTO budget.payment_methods_assigned_to_user VALUES (DEFAULT, $1, $2)'
const queryValues = [
req.user.id,
req.body.name
]
return db.query(addQuery, queryValues)
}
中,尝试在_document.js
标签下面添加脚本
<NextScript />
答案 1 :(得分:0)
我一直在研究类似的问题。
我尝试了上面的答案,将 <script>
标记放在 <body>
中,但不幸的是,它还将 <script>
标记生成的内容呈现给 DOM(例如,它运行脚本正确,但还将其中的所有额外数据存储在 <body>
标记的底部)。
我还尝试将脚本包装在来自 <Head>
的 next/head
组件中(仍在主体内部),这会阻止 DOM 呈现,但该修复根本没有运行脚本。>
最后,对我的用例有用的是将脚本加载移动到 _app.js
文件中:它可以正确运行脚本,而不会向 DOM 呈现额外的内容。它看起来像这样:
import Head from "next/head";
function MyApp({ Component, pageProps }) {
return (
<React.Fragment>
<Head>
<script
id="my-script"
src="https://scriptsource.com/script"
type="text/javascript"
></script>
</Head>
<LayoutComponent {...pageProps}>
<Component {...pageProps} />
</LayoutComponent>
</React.Fragment>
);
}
export default MyApp;
我不知道这个解决方案是否会导致任何我不知道的不良影响,但到目前为止它已经解决了我的问题。
更新(2021 年 6 月)
正如 Ahmed 在下面指出的,我上面写的解决方案有一些副作用。我注意到图像加载被脚本执行阻止。
我看到 Next 11 刚刚发布,其中包含用于此目的的新 <Script>
标签。
我把所有的props都移到了标签中,设置了strategy="beforeInteractive"
,然后直接把这个标签放到了Page组件中;现在一切都按预期运行。
以下是 Next 11 Script 标签的文档:https://nextjs.org/docs/basic-features/script