【问题标题】:Next.js Styled Components weird behaviourNext.js Styled Components 奇怪的行为
【发布时间】:2022-01-10 01:45:34
【问题描述】:

所以我正在做一个项目,但我的侧边栏组件的行为有点奇怪:

  • 我(重新)启动服务器,组件看起来像this
  • 我点击了一个链接项目/我访问了另一个 URL,它看起来像 this

我对组件知之甚少,更不了解样式化组件,所以我什至不知道从哪里开始。

components/Sidebar.ts

import React, { useState } from 'react';
import { SidebarData } from './SidebarData';
import styled from 'styled-components';
import * as Remix from 'react-icons/ri';
import Submenu from './Submenu';
import { useSession } from 'next-auth/react';


/* 
   --text-color: #ffffff;
  --text-secondary: #fefefe;
  --background-color: #091540;
  --background-secondary: #262c49;
  --background-third: #1a254d;
  --blue: #256EFF;
  --red: #FF495C;
  --green: #3DDC97;
*/

const Nav = styled.div`
   background: #091540;
   height: 8vh;
   display: flex;
   justify-content: flex-start;
   align-items: center;
   color: #ffffff;
`

const NavIcon = styled.div`
   margin-left: 2vw;
   font-size: 4vh;
   height: 8vh;
   display: flex;
   justify-content: flex-start;
   align-items: center;
   cursor: pointer;
`

const SidebarNav = styled.div`
   background: #091540;
   width: 25vh;
   height: 100%;
   display: flex;
   justify-content: center;
   position: fixed;
   top: 0;
   left: ${({ sidebar }) => (sidebar ? '0' : '-100%')};
   transition: 350ms;
   z-index: 10;
   color: #ffffff;
`

const SidebarWrap = styled.div`
   width: 100%;
`

const Sidebar = () => {

   const [sidebar, setSidebar] = useState(false);
   const toggleSidebar = () => setSidebar(!sidebar);
   const { data: session, status } = useSession();
   
   return (
      <div>
         <Nav>
            <NavIcon to="#">
               <Remix.RiMenuFill onClick={toggleSidebar} />
            </NavIcon>
         </Nav>
         <SidebarNav sidebar={sidebar}>
            <SidebarWrap>
            <NavIcon to="#">
               <Remix.RiMenuFoldFill onClick={toggleSidebar}/>
            </NavIcon>
            {SidebarData.map((item, index) => {
               if(session && item.disappearOnLogin === true && item.authRequired === false) return;
               if(!session && item.disappearOnLogin === false && item.authRequired === true) return;
               return <Submenu item={item} key={index}/>
            })}
            </SidebarWrap>
         </SidebarNav>
      </div>
   )
}

export default Sidebar;

如果需要更多代码,请在 Discord 上私信我:magma#5090

【问题讨论】:

标签: reactjs next.js styled-components next-auth


【解决方案1】:

所以基本上为了在服务器端渲染中使用样式化组件,您需要使用样式表再水化。当您的应用在服务器上呈现时,您可以创建一个 ServerStyleSheet 并向您的应用添加一个提供程序,该提供程序通过上下文 API 接受样式。

为此,您需要安装一个名为 babel-plugin-styled-components 的软件包

npm i babel-plugin-styled-components

然后,您想在项目的根目录中创建一个.babelrc 文件并将这些行添加到该文件中:

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}

然后你想去 pages 文件夹并创建一个 _document.js 页面。将以下代码添加到该文件中:

import Document from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
  static async getInitialProps(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();
    }
  }
}

有一种方法可以使用 .tsx 文件执行此操作,但我不确定这一点,并且使用 .js 文件对我有用,所以如果你愿意,我会让你找出 Typescript 版本。

重新启动您的服务器,您的样式组件应该可以正常使用了。

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 2021-11-10
    • 1970-01-01
    • 2021-08-25
    • 2022-08-09
    • 2018-10-13
    • 2019-05-11
    • 2021-04-06
    • 2017-08-02
    相关资源
    最近更新 更多