i18Next渲染两次,页面闪烁

时间:2018-11-27 14:07:56

标签: javascript redux styled-components next.js react-i18next

我用Next.js + react-i18next建立了一个网站。

我发现该网站将在首次加载时重新加载。它实际上并没有通过浏览器重新加载,就像该元素突然隐藏并突然显示)

我尝试禁用服务器端CSS(_document.js的样式组件),并且页面将呈现为渲染后加载的CSS。然后,我尝试禁用i18Next(删除i18NextProvider并在页面中不使用i18n),该页面没有重新加载问题。因此,我认为i18Next中的问题触发了服务器端渲染和客户端渲染之间的重新加载。

所有API都将在服务器端被调用,因此我认为服务器端渲染的代码已经很完美了。所以我有一些想法可以解决这个问题,但是我不知道该怎么办。

1)首次加载时阻止客户端渲染 2)仅更新服务器端和客户端之间的差异,而不重新加载整个容器

这是我的文件。

server.js

// @flow weak

const express = require('express')
const path = require('path')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev, dir: './src' })
const handle = app.getRequestHandler()

const i18nextMiddleware = require('i18next-express-middleware')
const Backend = require('i18next-node-fs-backend')
const i18n = require('./i18n')
const i18nCallBack = () => {
  app.prepare().then(() => {
    const server = express()

    server.use(i18nextMiddleware.handle(i18n))

    server.use('/locales', express.static(path.join(__dirname, '/locales')))

    server.get('*', (req, res) => {
      handle(req, res)
    })

    return server.listen(3000, err => {
      if (err) throw err
      console.log('> Ready on http://localhost:3000')
    })
  })
}
i18n
  .use(Backend)
  .use(i18nextMiddleware.LanguageDetector)
  .init(
    {
      fallbackLng: 'zh',
      preload: ['zh', 'en'],
      ns: ['common', 'menu', 'card', 'welcome'],
      backend: {
        allowMultiLoading: false,
        loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
        addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
      }
    },
    i18nCallBack
  )

module.exports = i18nCallBack

i18n.js

// @flow strict

const i18n = require('i18next')
const XHR = require('i18next-xhr-backend')
const LanguageDetector = require('i18next-browser-languagedetector')

const options = {
  fallbackLng: 'zh',
  lng: 'zh',
  load: 'languageOnly',
  ns: ['common'],
  defaultNS: 'common',
  debug: false,
  saveMissing: true,
  interpolation: {
    escapeValue: false,
    formatSeparator: ',',
    format: (value, format) => {
      if (format === 'uppercase') return value.toUpperCase()
      return value
    }
  },
  preload: ['en', 'zh']
}

// $FlowFixMe
if (process.browser) {
  i18n.use(XHR).use(LanguageDetector)
}

if (!i18n.isInitialized) i18n.init(options)

/* eslint-disable fp/no-mutation */
i18n.getInitialProps = (req, namespaces) => {
  let nss = namespaces
  if (!namespaces) nss = i18n.options.defaultNS
  if (typeof nss === 'string') nss = [nss]

  req.i18n.toJSON = () => null

  const initialI18nStore = {}
  req.i18n.languages.forEach(l => {
    initialI18nStore[l] = {}
    nss.forEach(ns => {
      initialI18nStore[l][ns] =
        (req.i18n.services.resourceStore.data[l] || {})[ns] || {}
    })
  })

  return {
    i18n: req.i18n,
    initialI18nStore,
    initialLanguage: req.i18n.language
  }
}

/* eslint-enable fp/no-mutation */
module.exports = i18n

0 个答案:

没有答案