简体   繁体   English

next.js将HOC中的道具传递给子组件getInitialProps

[英]next.js pass props from HOC to child components getInitialProps

I'd like to create an HOC for pages in my app that supplies some information kept in local storage for the case when the pages are not rendered on the server. 我想在我的应用程序中为页面创建一个HOC,在页面未在服务器上呈现时为本地存储提供一些信息。

I am only able to actually set the data from componentDidMount because I need access to localStorage (not avail. in Node env. obviously). 我只能实际设置componentDidMount的数据,因为我需要访问localStorage(显然在Node env中没有用)。

import * as React from 'react'
const withLogin = Page => class SecurePage extends React.Component {
  static async getInitialProps (ctx) {

    let language;
    if (ctx.req) {
        language = ctx.req.session.language;
    } else {
        language = localStorage.getItem('language');
    }

    let props = {}
    if (Page.getInitialProps) {
        const pageProps = await Page.getInitialProps(ctx);
        props = { ...pageProps, language }
    }

    console.log("this is what the props look like in the wrapping component", props)

    return props;

    // return Page.getInitialProps && { ...(await Page.getInitialProps(ctx)), language }
  }

  componentDidMount () {
      const { language } = this.props;
      if (language) {
          /* if we were able to fetch the language, set it here */
          localStorage.setItem('language', language);
      }
  }

  render () {
      console.log("pre-render page props ", this.props);
    return <Page {...this.props} /> 
  }
}

export default withLogin

When I go to outfit a component with it, the HOC getInitialProps function runs as expected, but it has no impact on the getInitialProps function of the rendered component. 当我使用它来装备组件时,HOC getInitialProps函数按预期运行,但它对渲染组件的getInitialProps函数没有影响。 Is there no way for me to pass props to the getInitialProps of a child component through HOC pattern? 我有没有办法通过HOC模式将道具传递给子组件的getInitialProps?

class EmployerJobList extends React.Component {
    static async getInitialProps(props) {

        if (props.req) {
            /* SSR */
            // language = req.session.language;
        } else {
            /* non-SSR */
            // language = user.preferred_language;
        }
        console.log("got language", props.language); // => undefined
        getUrl (`/api/localization?filename=create-job&language=${props.language}`)
        .then( jsonRes => {
            console.log(jsonRes);
        })
        ...
     export default withLogin(EmployerJobList)

If this is not a viable pattern; 如果这不是一个可行的模式; is there any reliable way for me to share/reuse the logic I am aiming for here with localStorage? 有没有可靠的方法让我与localStorage共享/重用我的目标逻辑?

I could theoretically do this in each Page component: 理论上我可以在每个Page组件中执行此操作:

static async getInitialProps(props) {

    let language;
    if (props.req) {
        /* SSR */
        language = req.session.language;
    } else {
        /* non-SSR */
        language = localStorage.getItem('language') // works
    }
    ...

But that seems unnecessarily redundant. 但这似乎是不必要的多余。

Was able to pass values into the child's getInitialProps function by supplying them as arguments: 能够通过提供它们作为参数将值传递给子的getInitialProps函数:

  static async getInitialProps (ctx) {
    let language;
    if (ctx.req) {
        language = ctx.req.session.language;
    } else {
        language = localStorage.getItem('language');
    }
    let props = {}
    if (Page.getInitialProps) {
        const pageProps = await Page.getInitialProps(ctx, language); // <--- this
        props = { ...pageProps, language }
    }
    return props;
  }

Then in the child component's getInitialProps I could access the new argument: 然后在子组件的getInitialProps中,我可以访问新参数:

static async getInitialProps({ query }, language) {

    console.log("is language passed through: ", language); // "en"
    const jobStatus = query.jobStatus;

    return { jobStatus }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM