无法使用NextJS

时间:2018-09-02 20:59:16

标签: materialize next.js

我正在使用Materialize CSS为正在使用的Web应用设置样式。我正在使用带有ReactJS的NextJS构建应用程序。我已经使用Materialize CSS文件中定义的类设置了导航栏的样式。但是,我无法使用规定的初始化脚本as instructed on the Materialize website来实现响应式边栏功能。

我的Navbar组件(./components/Navbar.js)看起来像这样:

import React, { Component, Fragment } from 'react';
import Link from 'next/link';
import $ from 'jquery';

class Navbar extends Component {
  constructor(props) {
    super(props)
    this.props = props;
  }

  componentDidMount = () => {
    document.addEventListener('DOMContentLoaded', function() {
      var elems = document.querySelectorAll('.sidenav');
      var instances = M.Sidenav.init(elems, options);
    });
  }

  render() {
    return (

      <Fragment>
        <nav>
          <div className="nav-wrapper blue">
            <Link prefetch href='/'>
              <a href="/" className="brand-logo">Project Coco</a>
            </Link>
            <a href="#" data-target="slide-out" className="sidenav-trigger"><i className="material-icons">menu</i></a>
            <ul id="nav-mobile" className="right hide-on-med-and-down">
              <li>
                <Link prefetch href='/'>
                  <a>Home</a>
                </Link>
              </li>
              <li>
                <Link prefetch href='/about'>
                  <a>About</a>
                </Link>
              </li>
              <li>
              </li>
            </ul>
          </div>
        </nav>
        {/* Sidenav markup */}
        <ul className="sidenav" id="slide-out">
          <li>
            <Link prefetch href='/'>
              <a>Home</a>
            </Link>
          </li>
          <li>
            <Link prefetch href='/about'>
              <a>About</a>
            </Link>
          </li>
        </ul>
      </Fragment>
    );
  }
}

export default Navbar;

很明显,此功能(边栏)需要JQuery。因此,我已经通过yarn添加了它,并正在使用import $ from 'jquery'调用它。但是在运行时,它抛出错误,提示 sidenav不是函数

我什至尝试完全放弃JQuery,而只是在componentDidMount中使用初始化脚本的原始JS版本:

document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('.sidenav');
    var instances = M.Sidenav.init(elems, options);
  });

但是这次,尽管没有错误,但该功能仍然无法正常工作,并且在汉堡菜单上单击不会触发应有的sidenav。

完整的代码仓库位于Github上,以供参考,原型应用程序位于schandillia.com。有解决方案吗?

P.S .:看来问题在于ComponentDidMount中的初始化代码在依赖它的MaterializeCSS.js(称为外部文件)之前执行。尽管这只是一个假设,但解决此问题的任何方法都可能是潜在的解决方案。

2 个答案:

答案 0 :(得分:3)

您需要将materialize-css导入到组件中。可悲的是,如果您尝试执行#page,则会收到fillPage错误。这是因为Next.js是通用的,这意味着它将在 import 'materialize-css'不存在的服务器端首先执行代码。我用于此问题的解决方法如下:

如果尚未安装,则安装materialize-css:

window is undefined

仅在定义了window的情况下,将Materialize-css导入到组件中:

$ npm i materialize-css

然后,在您的window方法中:

if (typeof window !== 'undefined') {
    window.$ = $;
    window.jQuery = $;
    require('materialize-css');
}

所以您的组件看起来像这样:

componentDidMount

来源:Next.js FAQthis issue

答案 1 :(得分:0)

这个怎么样:-

  • _app.tsx
import 'materialize-css/dist/css/materialize.min.css';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;

  • index.tsx
import React, { useEffect } from 'react';

const Index = () => {
  useEffect(() => {
    const M = require('materialize-css');
    M.toast({ html: 'worlds' });
  }, []);

  return (
    <div className='container'>
      <h1>hello</h1>
    </div>
  );
};

export default Index;