i18Следующий рендеринг дважды и страница мигает - PullRequest
0 голосов
/ 27 ноября 2018

Я использовал Next.js + реагировать-i18 для создания веб-сайта.

Я обнаружил, что веб-сайт будет перезагружен при первой загрузке.На самом деле он не перезагружается через браузер, как будто элемент внезапно скрывается и неожиданно отображается)

Я пытаюсь отключить CSS на стороне сервера (styled-component of _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
...