如何在 react/Gatsby 上使用自定义 Js 模板文件?

How to use custom Js template file on react/Gatsby?

这是我第一次来这里。我已经花了两天时间试图解决这个问题。

我是 react/gatsby 开发的新手,我购买了一个带有 CSS/js 文件的 html 模板,我找到了导入 CSS 文件的方法,实际上gatsby-ssr.js 上的 js 文件,当我 运行 gatsby develop 命令时,站点在控制台上给我下一个错误,停止模板 js 文件工作:

react-dom.development.js:67 Warning: Expected server HTML to contain a matching <p> in <div>.
at p
at div
at div
at div
at div
at div
at div
at section
at div
at StaticQueryDataRenderer

但是当我 运行 gatsby 服务时,就像在生产中一样,错误消失了,js 文件可以完美运行。 已经尝试使用“useEffect”来控制 DOM 对象,但是模板中的自定义 js 文件使用 jQuery 来使用由 gatsby-ssr.js 文件上的 js 文件加载的另一个库。也试过修改默认html.js 无解

我认为是执行时间,这些js模板文件需要在html页面渲染结束时加载,那是因为在html模板中工作正常,但在react组件中没有导入自定义 js 模板文件。

我想要的只是摆脱红色警告控制台标志,让自定义 js 模板文件正常工作,同时我处于 gatsby 的开发模式。我快疯了哈哈

Edit

我将尝试解释我在做什么以及它应该如何工作。

1: 该模板有一个名为 main.js 的文件,其中包含此代码。

    if ($('#breaking_slider').length > 0) {
        $('#breaking_slider').owlCarousel({
            items: 1,
            loop: true,
            dots: false,
            nav: true,
            animateOut: 'slideOutDown',
            animateIn: 'flipInX',
            autoplayTimeout: 5000,
            autoplay: true,
        })
    }

2: 我使用 gatsby-ssr.js 导入 main.js 文件是这样的。

    import React from 'react'
    import { withPrefix, Link } from "gatsby"

    export const replaceRenderer = ({ setPostBodyComponents }) => {
       setPostBodyComponents([
            // .... more template scripts
            <script
                key={withPrefix('main.js')}
                src={withPrefix('main.js')}
                crossOrigin="anonymous"
                defer
            />,
      ])
    }

3: 使用下一个代码创建了一个名为 nav 的组件,我在 layout.js 和 index.js 页面上使用了它

    <section className="top-bar transparent">
        <div className="container">
            <div className="row">
                <div className="col-md-12 align-self-center">
                    <div className="ts-breaking-news clearfix">
                        <h2 className="breaking-title float-left">
                            <i className="fa fa-bolt"></i> Breaking News :</h2>
                        <div className="breaking-news-content owl-carousel float-left" id="breaking_slider">
                            <div className="breaking-post-content">
                                <p>
                                    <a href="./">Netcix cuts out the chill with an integrated personal trainer on running.</a>
                                </p>
                            </div>
                            <div className="breaking-post-content">
                                <p>
                                    <a href="./">Parquet Courts on Resisting Nihilism & Why Tourism in Dubai is booming the world.</a>
                                </p>
                            </div>
                            <div className="breaking-post-content">
                                <p>
                                    <a href="/">Parquet Courts on Resisting Nihilism & Why Tourism in Dubai is booming the world.</a>
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

4:当我使用命令 gatsby develop 一秒钟时,index.js 运行良好,使用 main.js 并修改 DOM 对象,但之后会抛出下一个错误在控制台上并在第一秒停止执行 main.js 和修改后的视觉效果。

    react-dom.development.js:67 Warning: Expected server HTML to contain a matching <p> in <div>.
    at p
    at div
    at div
    at div
    at div
    at div
    at div
    at section
    at div
    at StaticQueryDataRenderer

5:如果我真的使用 gatsby serve 命令而不是 gatsby develop 就像在生产中一样,错误消失了,但最好奇的是 main.js 执行永远不会停止,所以组件运行良好,实际上模板在 gatsby-ssr.js 中使用的 js 文件就像假设的那样工作。

结论:我的想法是执行流程,我对PHP这样的语言有经验,模板的顺序可以解决这样的问题,但是从来没有在react上深入使用js这样的语言,我知道这与编译 js 文件不同,但我试图移动加载此 js 模板文件的位置,我试图用组件内部的实际 useEffect 替换 main.js,但 main.js 在 jQuery 并使用以相同方式加载的其他库,因此不能解决问题。

感谢大家阅读这篇文章,它很长,但必须描述发生了什么才能以更好的方式表达我的问题。

有很多要评论的,但我建议您去掉 jQuery 并在您的模板中像这样导入:

if ($('#breaking_slider').length > 0) {
    $('#breaking_slider').owlCarousel({
        items: 1,
        loop: true,
        dots: false,
        nav: true,
        animateOut: 'slideOutDown',
        animateIn: 'flipInX',
        autoplayTimeout: 5000,
        autoplay: true,
    })
}

这个文件,直接指向 DOM 而不是 React 生成的虚拟 DOM (vDOM) 永远不会被卸载。这意味着,因为它在 React 的范围之外(React 不知道真正的变化 DOM),通过页面导航永远不会停止那些文件的执行,这意味着性能的巨大下降(这个功能看似毫无意义,但资源正在积累。

您可以使用 owl-carousel 基于 React 的库在基于 React 的环境中轻松重构这样的函数:

<OwlCarousel className='owl-theme' loop margin={10} nav>
    <div class='item'>
        <h4>1</h4>
    </div>
    <div class='item'>
        <h4>2</h4>
    </div>
    <div class='item'>
        <h4>3</h4>
    </div>
</OwlCarousel>

这就是为什么确实存在特定的基于 React 的依赖项的原因。

上面的代码片段可以是一个独立的组件。

如果您仍想将 jQuery 与 React 集成,我将在答案末尾添加 React 文档中的集成示例,但请记住您需要处理这种 mounting/unmounting副作用。

关于您的警告:检查组件的结构。它应该是这样的:

export default function NavBar(props){

return    <section className="top-bar transparent">
        <div className="container">
            <div className="row">
                <div className="col-md-12 align-self-center">
                    <div className="ts-breaking-news clearfix">
                        <h2 className="breaking-title float-left">
                            <i className="fa fa-bolt"></i> Breaking News :</h2>
                        <div className="breaking-news-content owl-carousel float-left" id="breaking_slider">
                            <div className="breaking-post-content">
                                <p>
                                    <a href="./">Netcix cuts out the chill with an integrated personal trainer on running.</a>
                                </p>
                            </div>
                            <div className="breaking-post-content">
                                <p>
                                    <a href="./">Parquet Courts on Resisting Nihilism & Why Tourism in Dubai is booming the world.</a>
                                </p>
                            </div>
                            <div className="breaking-post-content">
                                <p>
                                    <a href="/">Parquet Courts on Resisting Nihilism & Why Tourism in Dubai is booming the world.</a>
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

}

created a component called nav with the next code, which I use on a layout.js and a index.js page

理想情况下,您的 index.js 应该从您的 Layout 扩展,这样您就不需要两次导入导航栏,因为一旦您在布局中导入它,它就会可用在 index.js.

const Layout = ({children})=>{
return <main>
   <NavBar />
   {children}
   </main>
}

资源: