簡體   English   中英

Next.js / React-如何從Apollo客戶端HOC通用解析用戶語言?

[英]Next.js/React - How to universally resolve the user language, from an Apollo client HOC?

我正在使用Next.js框架(v5)開發I18n模塊。

為了顯示對用戶的默認語言的用戶界面,我想弄清楚這是什么語言, 普遍

從瀏覽器解析語言是“相當簡單”的,但是我很難弄清楚如何在服務器端做到這一點, 同時為包裝我的Page的HOC提供該值,以便我可以在其中指定請求headers以使用該語言環境,以便以該語言獲取內容。

我想出了如何使用pages/_documents.jsaccept-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'}

這很好。

但是,我需要在包裝頁面組件的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而被阻止。

Redux的想法是使用getInitialProps解析語言並將其存儲在redux中,然后在運行graphql() HOC查詢之前連接到商店,因此使該語言在graphql HOC的props中可用,以便我可以使用正確的標題運行查詢。

但是如上所述,Redux在服務器端不可用,嘗試通過_document.js進行初始化_document.js服務器崩潰。 參見https://github.com/zeit/next.js/issues/3990#issuecomment-372159451

餅干

我也嘗試使用cookie,但是雖然我成功地從兩個瀏覽器/服務器讀取cookie,但無法在_document.js getInitialProps函數內的服務器端寫入它們。 我不知道為什么, 現有的例子也沒有幫助我。

您可以從HOC訪問getInitialPropsgetInitialProps的限制照常適用(沒有子組件,只有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 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM