zhangyuang / ssr

A most advanced ssr framework support React17/React18/Vue2/Vue3 on Earth that implemented serverless-side render specification.
http://doc.ssr-fc.com/
MIT License
2.61k stars 284 forks source link

layout布局问题 #112

Closed wuyiifan closed 3 years ago

wuyiifan commented 3 years ago

提问前请确认以下几点信息,否则你的问题将不会被解答

详细描述你的问题

第一个问题: ssr模式时 layout/App.tsx文件

const App = (props: LayoutProps) => {
  const { state } = useContext(window.STORE_CONTEXT)
  const i18nConfig = initLocal('en_US')

  let path = state.path

  if (__isBrowser__) {
    path = location.pathname
  }

  return (
    <ConfigProvider csp={{ nonce: 'YourNonceCode' }} locale={i18nConfig.antd}>
      <IntlProvider
        locale={i18nConfig.locale}
        messages={i18nConfig.messages}
      >
        {['/admin/settings', '/admin/billing'].includes(path)
          ? (
            <BlankAdmin>
              {props.children!}
            </BlankAdmin>
          )
          : (
            <AdminLayout>
              {props.children!}
            </AdminLayout>
          )
        }

      </IntlProvider>
    </ConfigProvider>
  )
}

有一个错误 image

我也检查了useEffect的监听,在组件销毁前都做了取消的逻辑。而且layout放在App.tsx里在csr模式页面会空白。

第二个问题:

AdminLayout 放在页面路由上,这时通过<Link to="">前端跳转页面的话,目标页面会闪烁刷新(首次),

期望的结果

根据path展示不同的layout,同时能兼容csr的模式。 layout放在页面组件上也可以,但是不要首次闪烁。

当前使用的版本

复现仓库地址

你本人对问题可能的原因判断(如果你能大概判断的话)

报错原因我猜测是在切换路由时执行这个布局选择,之前的useEffect效果没有被取消同时又触发出发新的渲染

 {['/admin/settings', '/admin/billing'].includes(path)
    ? (
      <BlankAdmin>
        {props.children!}
      </BlankAdmin>
    )
    : (
      <AdminLayout>
        {props.children!}
      </AdminLayout>
    )
  }
zhangyuang commented 3 years ago

跟框架无关,明显是你自己的代码问题,解决不了就给最简复现仓库

wuyiifan commented 3 years ago

跟框架无关,明显是你自己的代码问题,解决不了就给最简复现仓库

好的 稍后我弄一个仓库

wuyiifan commented 3 years ago

网速不好弄了两个压缩包 切换路由报错问题.zip layout放在页面里首次(页面元素少 闪烁的比较快).zip

zhangyuang commented 3 years ago

你两个逻辑分支的 props.children 外层的 DOM 结构没对齐,按照下面的改

           <div className={styles.one}>
+            <div>
             {props.children}
+            </div>
           </div>
wuyiifan commented 3 years ago

我在children外层包了一个div确实没有问题了. 想知道为啥这么写就好了。

zhangyuang commented 3 years ago

dom结构对不上,具体解释需要去看react源码

wuyiifan commented 3 years ago

还有个问题: 路由切换多次后state.path就不更新了 这个时候该使用history.listern去监听么,还是在页面级的fetch.ts再次返回state.path

wuyiifan commented 3 years ago
import { ISSRContext } from 'ssr-types-react'
import { RouteComponentProps } from 'react-router'
import { Context } from 'egg'

export default async (ctx: ISSRContext<Context> | RouteComponentProps) => {
  console.log('setting fetch')
  return {
    path: __isBrowser__ ? (ctx as RouteComponentProps).match.path : (ctx as Context).request.path
  }
}

尝试页面去设置不行,只能用history.listern了。

zhangyuang commented 3 years ago

不更新,最新版本已修复@5.6.19 发布中

wuyiifan commented 3 years ago

还有在csr模式时,App.tsx下的layout布局应该不能用了吧

wuyiifan commented 3 years ago

好的稍后我更新下

zhangyuang commented 3 years ago

可以用啊,csr只针对页面组件,app.tsx里面的东西不管是哪种模式都会在服务端运行

wuyiifan commented 3 years ago

框架越来越健壮了

wuyiifan commented 3 years ago

在示例代码里按照你给的方式修改没问题,在我的主项目里还是有这个 image

wuyiifan commented 3 years ago
// 此文件将会在服务端/客户端都将会用到
// 可通过 __isBrowser__ 或者 useEffect 判断当前在 浏览器环境做一些初始化操作
import { LayoutProps } from 'ssr-types-react'
import React, { memo, useContext, useEffect, useState } from 'react'
import initLocal from '@/locale'
import UserLayout from './UserLayout'
import Logo from '@/components/common/logo'
import AdminTopNav from '@/components/common/admin-header'
import AnalyticsOverview from '@/components/analytics'
import AdminHeader from '@/components/common/admin-header'
import styles from './layout.module.less'
import ValaditeEmail from '@/components/common/notice/valadite-email'
import { useHistory } from 'react-router-dom'

import SidebarMenu from '@/components/common/sidebar'

// navigator.language.split('-')[0]
const AdminLayout = (props: LayoutProps) => {
  const history = useHistory()
  const { state } = useContext(window.STORE_CONTEXT)
  const [path, setPath] = useState(state?.path)

  useEffect(() => {
    const unlisten = history.listen(({ pathname }) => {
      setPath(pathname)
    })

    return () => {
      unlisten()
    }
  }, [])

  if (!path) return null

  if (['/admin/billing', '/admin/settings'].includes(path)) {
    return (
      <div className={styles.layout}>
        <SidebarMenu></SidebarMenu>

        <div className={styles['main-content']}>
          <header className={styles.header}>
            <AdminHeader></AdminHeader>
          </header>
          <div className={styles.one}>
            <div>
              {props.children!}
            </div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className={styles.layout}>
      <SidebarMenu ></SidebarMenu>

      <div className={styles['main-content']}>
        <header className={styles.header}>
          <AdminHeader></AdminHeader>
        </header>

        <AnalyticsOverview></AnalyticsOverview>

        <div className={styles.wrapper}>
          <div className={styles.content}>
            <div>
              {props.children!}
            </div>
          </div>

          <div className={styles.preview}>
            <div className={styles.phone}>

            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

export default memo(AdminLayout)

目前是这个解决方案

wuyiifan commented 3 years ago

加个history.listen

zhangyuang commented 3 years ago

path不更新的你装最新依赖就行了啊

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: wuyiifan @.> 发送时间: 2021年9月7日 20:38 收件人: ykfe/ssr @.> 抄送: yuuang @.>, Comment @.> 主题: 回复:[ykfe/ssr] layout布局问题 (#112)

加个history.listen

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

wuyiifan commented 3 years ago

更新过了

"dependencies": {
    "@ant-design/icons": "^4.6.3",
    "@mailchimp/mailchimp_marketing": "^3.0.58",
    "@midwayjs/cache": "^2.12.7",
    "@midwayjs/decorator": "^2.12.3",
    "@midwayjs/swagger": "^1.0.7",
    "@midwayjs/web": "^2.12.7",
    "@paypal/react-paypal-js": "^7.2.1",
    "@types/cache-manager": "^3.4.2",
    "antd": "^4.16.12",
    "antd-mobile": "^2.3.4",
    "axios": "^0.21.1",
    "cache-manager": "^3.4.4",
    "classnames": "^2.3.1",
    "egg": "^2.30.0",
    "egg-mysql": "^3.0.0",
    "egg-scripts": "^2.14.0",
    "geoip-lite": "^1.4.2",
    "midway-marketing": "^1.0.2",
    "mysql": "^2.18.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-intl": "^5.20.10",
    "react-router-dom": "^5.3.0",
    "ssr-core-react": "^5.6.17",
    "ssr-types-react": "^5.6.19",
    "swagger-ui-dist": "^4.0.0-beta.4"
  }

已经是最新的了

zhangyuang commented 3 years ago

改什么版本号啊。。。删了lock装最新的啊,装了最新的还不行那就很明显是你自己的问题

wuyiifan commented 3 years ago

image 更具报错内容定位到了这个文件,是你下午刚更改的内容么

zhangyuang commented 3 years ago

你要是还有问题就直接给复现这样一问一答效率很低

wuyiifan commented 3 years ago

example2.zip 这是升级后的包

zhangyuang commented 3 years ago

image 一个问题啊结构对不上

wuyiifan commented 3 years ago

没理解这个结构要和谁对上 把这个注释掉确实可以 这是啥规律啊 把他注释掉 布局就改结构了 image

zhangyuang commented 3 years ago

你保证 props.children 的父结构也就是div 的嵌套层级完全一致就行了

wuyiifan commented 3 years ago

我捋了一下 props.children的外层div的层数要保持一致 这样就行了

应该是这个意思

wuyiifan commented 3 years ago

如果这样的话我想根据path使用不同的布局的同时还要考虑嵌套的层级 这有点难受呀

wuyiifan commented 3 years ago

还是达不到我想要的效果,使用不同的layout布局,能帮忙写一个示例代码么

zhangyuang commented 3 years ago

更新了一版,参考最新文档 http://doc.ssr-fc.com/docs/features$faq#%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%20Layout

wuyiifan commented 3 years ago

更新了一版,参考最新文档 http://doc.ssr-fc.com/docs/features$faq#%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%20Layout

我一会试试

wuyiifan commented 3 years ago

ok 问题修复了 你是把dom结构对不上的问题给修复了吧