SuperYan - nextJs https://www.hblyan.com/tag/nextJs/ zh-CN Mon, 10 Apr 2023 14:43:00 +0800 Mon, 10 Apr 2023 14:43:00 +0800 【解决方案】next.js 富文本编辑器build失败?SSR渲染引入第三方组件打包错误等@wangeditor/editor https://www.hblyan.com/archives/141.html https://www.hblyan.com/archives/141.html Mon, 10 Apr 2023 14:43:00 +0800 SuperYan

背景:next.js 项目中 引入@wangeditor/editor 编辑器 在build时候,该依赖报错 ReferenceError: Element is not defined 导致无法成功发布

方案:利用 dynamic 动态引入该组件取消ssr渲染,改为cli端 渲染即可

应用:第三方插件不支持ssr渲染

报错

原来报错的代码就不写了,就是该富文本按照react的方式引入页面文件中,导致报错

image-20230410141322398.png

很明显 这个问题就是在打包的环境的中(node)中没有Element变量支持,因为这个变量在window上。

解决方案

//  /components/MyEdit.tsx
import React, { useEffect, useState } from 'react'
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
import { IDomEditor, IEditorConfig, IToolbarConfig, SlateDescendant } from "@wangeditor/editor";
import '@wangeditor/editor/dist/css/style.css'

interface Props {
    html: any,
    setHtmlFn: any
}
export default function MyEditor(props: Props) {
    const { html, setHtmlFn } = props
    const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法

    useEffect(() => {
        return () => {
          if (editor == null) return;
          editor.destroy();
          setEditor(null);
        };
      }, [editor]);
      
    const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
    const editorConfig: Partial<IEditorConfig> = {
        placeholder: "请输入内容...",
    };

    return (
        <div style={{ border: "1px solid #ccc", zIndex: 100 }}>
            <Toolbar
                editor={editor}
                defaultConfig={toolbarConfig}
                mode="default"
                style={{ borderBottom: "1px solid #ccc" }}
            />
            <Editor
                defaultConfig={editorConfig}
                value={html}
                onCreated={setEditor}
                onChange={(editor: any) => setHtmlFn(editor.getHtml())}
                mode="default"
                style={{ height: "500px", overflowY: "hidden" }}
            />
        </div>
    )
}
// 页面代码
...
import dynamic from 'next/dynamic'

const ReactWEditor = dynamic(import("../../../components/MyEditor"), {
  ssr: false,
  loading: () => <p>Loading ...</p>, 
});

...
const Page = () => {
 const [attachments, setAttachments] = useState<any[]>([]);
 const [html, setHtml] = useState("");
 return (
 <div>
     <ReactWEditor html={html} setHtmlFn={setHtml} />
 </div>
 
 )
}
  
  

按照上述代码配置后 ,该富文本插件的代码就会在 客户端 渲染该组件就不会有打包时候的问题了。

]]>
3 https://www.hblyan.com/archives/141.html#comments https://www.hblyan.com/feed/tag/nextJs/
【解决方案】如何在Next js中创建多个布局 ? 404登录注册页等 https://www.hblyan.com/archives/135.html https://www.hblyan.com/archives/135.html Sat, 25 Mar 2023 09:52:00 +0800 SuperYan

背景:项目封装了全局的layout(导航顶部 以及底部),增加登录注册页面或者其他独立的页面,如何不渲染在全局的layout中?

方案:在_app.js页面中 作多套渲染方案,通过getlayout 属性自定义

应用:独立页面

全局layout

import React, { ReactNode } from 'react'
import Footer from './MyFooter'
import Header from './MyHeader'
import { Layout } from 'antd'

const { Content } = Layout

const MLayout: React.FC<{ children: ReactNode }> = ({ children }) => {


    return (
        <Layout>
            <Header />
            <Content>
                {children}
            </Content>
            <Footer />
        </Layout>

    )
}


export default MLayout

_app.tsx

import '@/styles/reset.css'
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import 'antd/dist/reset.css';
import MLayout from '../../layout';
import type { NextPage } from 'next'
import type { ReactElement, ReactNode } from 'react'

type NextPageWithLayout = NextPage & {
  getLayout?: (page: ReactElement) => ReactNode
}

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}

export default function App({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page) => page)
  //是否应用页面的自定义layout 如果没有定义 则使用默认的全局layout 
  //通常定义404 以及登录注册等 独立页面
  if (Component.getLayout) return getLayout(<Component {...pageProps} />)
  else return <MLayout> <Component {...pageProps} /></MLayout>
}

404 页面

import React, { ReactNode } from 'react'

export default function Index() {
    return (
        <div>
            404
        </div>
    )
}

Index.getLayout = function getLayout(page: ReactNode) {
    return <>{page}</>
}

如果页面中 不增加自定义的getLayout 属性方法的话,就是走全局的layout渲染

]]>
1 https://www.hblyan.com/archives/135.html#comments https://www.hblyan.com/feed/tag/nextJs/