【问题标题】:Next.js/React - How to universally resolve the user language, from an Apollo client HOC?Next.js/React - 如何从 Apollo 客户端 HOC 普遍解析用户语言?
【发布时间】:2020-01-12 09:59:04
【问题描述】:

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

为了以用户的默认语言显示 UI,我试图弄清楚该语言是什么,普遍

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

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

  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'}

这很好用。

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

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 查询之前连接到商店,从而使语言在 props 中可用graphql HOC,以便我可以使用正确的标题运行查询。

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

Cookies

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

【问题讨论】:

    标签: javascript next.js react-apollo apollo-client high-order-component


    【解决方案1】:

    您可以从 HOC 访问 getInitialProps - 对 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.

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

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2021-04-21
      • 2020-08-23
      • 2020-07-22
      • 2021-10-12
      • 2020-01-24
      • 2019-07-25
      • 1970-01-01
      • 2022-12-12
      相关资源
      最近更新 更多