1

我正在使用 Next.js 框架 (v5) 开发 I18n 模块。

为了以用户的默认语言显示 UI,我试图找出该语言是什么,普遍的。

从浏览器解析语言“相当简单”,但我很难弄清楚如何在服务器端做到这一点,同时将该值提供给包装我的页面的 HOC,以便我可以在我的请求headers使用的语言环境,以获取该语言的内容。

我想出了如何使用accept-language标头从服务器解析用户的语言pages/_documents.js

  static getInitialProps(props) {
    const { req, res, renderPage, isServer = false } = props;
    const cookies = new Cookies();

    if (isServer) {
      const headers = req.headers;
      const acceptedUserLanguages = acceptLanguageParser.parse(headers['accept-language']);
      const mostPreferredLanguage = get(acceptedUserLanguages, '[0]', {});
      // {code: 'en', region: 'GB'}

这工作正常。

但是,我需要mostPreferredLanguage在包装 Page 组件的 HOC 中访问它,我真的不知道该怎么做,因为 HOC 代码是在函数之前执行的getInitialPropsreq.headers据我所知,我无法从 HOC 本身访问。

HOC实施:

export default withData(
  compose(
    withRedux(configureStore),
    withLoanAdvisor,
    graphql(institutionPagesData, {
      options: (props) => {
        return {
          context: {
            headers: {
              'gcms-locale': 'FR', // How do I universally get the user language here? I don't have access to request.headers there
              'gcms-locale-no-default': false
            },
          },
        };
      },
    }),
  )(SchoolPage));

潜在的解决方案

还原

我一直在考虑使用Redux。我试图实现它但被阻止了,因为它似乎无法在服务器端使用 Redux。

Redux 的想法是用来getInitialProps解析语言并将其存储在 redux 中,然后在运行我的graphql()HOC 查询之前连接到商店,因此使语言在 HOC 中可用propsgraphql以便我可以运行查询正确的标题。

但如前所述,Redux 在服务器端不可用,并试图通过_document.js使服务器崩溃来初始化它。见https://github.com/zeit/next.js/issues/3990#issuecomment-372159451

饼干

我也尝试使用 cookie,但是当我成功地从浏览器/服务器读取 cookie 时,我无法在_document.js getInitialProps函数内部的服务器端写入它们。我不知道为什么,现有的例子并没有帮助我。

4

1 回答 1

3

您可以getInitialProps从 HOC 访问 - 像往常一样应用的限制getInitialProps(没有子组件,只有pages),但这是很常见的模式,例如:

const withSize = (WrappedComponent) => {
  return class extends React.Component {
    static async getInitialProps({ req }) {
      const ua = req ? req.headers['user-agent'] : navigator.userAgent;
      const userAgent = uaParser(ua);

      return { userAgent };
    }

    // ... implementation

    render() {
      // userAgent meant to be removed from props
      const { userAgent, ...props } = this.props || {};
      return (
        <WrappedComponent
          {...props}
          {...this.state}
          isMobile={this.state.windowWidth <= deviceWidth.mobile}
          isTablet={this.state.windowWidth <= deviceWidth.tablet}
        />
      );
    }
  };
};

有关更多示例,请参见 nextjs 的示例,例如https://github.com/zeit/next.js/blob/3e51ddb8af55b6438aa3aeb382081b9a1c86f325/examples/with-lingui/components/withLang.js

hoistNonReactStatics(如果您还想getInitialProps在 HOC 包装的组件中使用,请不要忘记。)

于 2019-09-17T07:22:49.883 回答