javascript - Next.js/React - 如何从 Apollo 客户端 HOC 通用解析用户语言?

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

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

为了以用户的默认语言显示 UI,我正在尝试弄清楚该语言是什么,通用

从浏览器解析语言“相当简单”,但我很难弄清楚如何在服务器端执行此操作,同时将该值提供给包装的 HOC我的页面,以便我可以在请求 header 中指定要使用的区域设置,以便获取该语言的内容。

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

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

这很好用。

但是,我需要在包装页面组件的 HOC 中访问这个 mostPreferredLanguage,我真的不知道该怎么做,因为 HOC 代码是在 之前 getInitialProps 函数。据我所知,我无法从 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 之前连接到存储查询,因此使语言在 graphql HOC 的 props 中可用,以便我可以使用正确的 header 运行查询。

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

Cookie

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

最佳答案

您可以从 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。)

关于javascript - Next.js/React - 如何从 Apollo 客户端 HOC 通用解析用户语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57874262/

相关文章:

javascript - 即使使用 parseInt 转换计算后我仍然得到 NaN

javascript - 下一个JS : How to send data from one page to another page's getInitialProps function

reactjs - GraphQLError : Syntax Error: Expected $, found [

reactjs - 如何从apollo缓存中获取更新的数据

graphql - 使用 GraphQL Apollo 同时进行轮询和分页?

javascript - 网页设计 : Client wants a rotation-based navigation bar

javascript - 源 map 资源管理器中的未映射字节是什么

JavaScript:如何将数组值与每个匹配项匹配,而不是与所有匹配项匹配

javascript - 使用 _document.js 在正文上使用 Next.js 自定义类

css - :global() css-module selectors not being pure in NextJS 问题