Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用HOC访问Next.js getInitialProps中的React.Context_Javascript_Reactjs_Next.js_React Context - Fatal编程技术网

Javascript 使用HOC访问Next.js getInitialProps中的React.Context

Javascript 使用HOC访问Next.js getInitialProps中的React.Context,javascript,reactjs,next.js,react-context,Javascript,Reactjs,Next.js,React Context,我试图通过使用一个简单的服务来抽象我的API调用,该服务提供了一个非常简单的方法,这只是一个HTTP调用。我将此实现存储在React上下文中,并在我的\u app.js中使用它的提供程序,这样API就可以在全球范围内使用,但我在实际使用页面中的上下文时遇到了问题 pages/_app.js import React from 'react' import App, { Container } from 'next/app' import ApiProvider from '../Provide

我试图通过使用一个简单的服务来抽象我的API调用,该服务提供了一个非常简单的方法,这只是一个HTTP调用。我将此实现存储在React上下文中,并在我的
\u app.js
中使用它的提供程序,这样API就可以在全球范围内使用,但我在实际使用页面中的上下文时遇到了问题

pages/_app.js

import React from 'react'
import App, { Container } from 'next/app'

import ApiProvider from '../Providers/ApiProvider';

import getConfig from 'next/config'
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()

export default class Webshop extends App 
{
    static async getInitialProps({ Component, router, ctx }) {
        let pageProps = {}

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps }
    }

    render () {
        const { Component, pageProps } = this.props

        return (
            <Container>
                <ApiProvider endpoint={publicRuntimeConfig.api_endpoint}>
                    <Component {...pageProps} />
                </ApiProvider>
            </Container>
        );
    }
}
import fetch from 'unfetch'

function Api (config)
{
    const apiUrl = config.endpoint;

    async function request (url) {
        return fetch(apiUrl + '/' + url);
    };

    this.decode = async function (code) {
        const res = request('/decode?code=' + code);
        const json = await res.json();
        return json;
    }

    return this;
}

export default Api;
import React, { Component } from 'react';
import Api from '../Services/Api';

const defaultStore = null;

class ApiProvider extends React.Component
{
    state = {
        api: null
    };

    constructor (props) {
        super(props);

        this.state.api = new Api({ endpoint: props.endpoint });
    }

    render () {
        return (
            <ApiContext.Provider value={this.state.api}>
                {this.props.children}
            </ApiContext.Provider>
        );
    }
}

export const ApiContext = React.createContext(defaultStore);
export default ApiProvider;
export const ApiConsumer = ApiContext.Consumer;
export function withApi(Component) {
    return function withApiHoc(props) {
        return (
            <ApiConsumer>{ context => <Component {...props} api={context} /> }</ApiConsumer>
        )
    }
};
import React, { Component } from 'react';
import Link from 'next/link';
import { withApi } from '../Providers/ApiProvider';

class Code extends React.Component
{
    static async getInitialProps ({ query, ctx }) {
        const decodedResponse = this.props.api.decode(query.code); // Cannot read property 'api' of undefined

        return {
            code: query.code,
            decoded: decodedResponse
        };
    }

    render () {
        return (
            <div>
                [...]
            </div>
        );
    }
}

let hocCode = withApi(Code);
hocCode.getInitialProps = Code.getInitialProps;
export default hocCode;
Providers/ApiProvider.js

import React from 'react'
import App, { Container } from 'next/app'

import ApiProvider from '../Providers/ApiProvider';

import getConfig from 'next/config'
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()

export default class Webshop extends App 
{
    static async getInitialProps({ Component, router, ctx }) {
        let pageProps = {}

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps }
    }

    render () {
        const { Component, pageProps } = this.props

        return (
            <Container>
                <ApiProvider endpoint={publicRuntimeConfig.api_endpoint}>
                    <Component {...pageProps} />
                </ApiProvider>
            </Container>
        );
    }
}
import fetch from 'unfetch'

function Api (config)
{
    const apiUrl = config.endpoint;

    async function request (url) {
        return fetch(apiUrl + '/' + url);
    };

    this.decode = async function (code) {
        const res = request('/decode?code=' + code);
        const json = await res.json();
        return json;
    }

    return this;
}

export default Api;
import React, { Component } from 'react';
import Api from '../Services/Api';

const defaultStore = null;

class ApiProvider extends React.Component
{
    state = {
        api: null
    };

    constructor (props) {
        super(props);

        this.state.api = new Api({ endpoint: props.endpoint });
    }

    render () {
        return (
            <ApiContext.Provider value={this.state.api}>
                {this.props.children}
            </ApiContext.Provider>
        );
    }
}

export const ApiContext = React.createContext(defaultStore);
export default ApiProvider;
export const ApiConsumer = ApiContext.Consumer;
export function withApi(Component) {
    return function withApiHoc(props) {
        return (
            <ApiConsumer>{ context => <Component {...props} api={context} /> }</ApiConsumer>
        )
    }
};
import React, { Component } from 'react';
import Link from 'next/link';
import { withApi } from '../Providers/ApiProvider';

class Code extends React.Component
{
    static async getInitialProps ({ query, ctx }) {
        const decodedResponse = this.props.api.decode(query.code); // Cannot read property 'api' of undefined

        return {
            code: query.code,
            decoded: decodedResponse
        };
    }

    render () {
        return (
            <div>
                [...]
            </div>
        );
    }
}

let hocCode = withApi(Code);
hocCode.getInitialProps = Code.getInitialProps;
export default hocCode;
import React,{Component}来自'React';
从“../Services/Api”导入Api;
const defaultStore=null;
类ApiProvider扩展了React.Component
{
状态={
api:null
};
建造师(道具){
超级(道具);
this.state.api=新api({endpoint:props.endpoint});
}
渲染(){
返回(
{this.props.children}
);
}
}
export const ApiContext=React.createContext(defaultStore);
导出默认ApiProvider;
export const ApiConsumer=ApiContext.Consumer;
使用API导出函数(组件){
带APIhoc(道具)的返回函数{
返回(
{context=>}
)
}
};
页面/code.js

import React from 'react'
import App, { Container } from 'next/app'

import ApiProvider from '../Providers/ApiProvider';

import getConfig from 'next/config'
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()

export default class Webshop extends App 
{
    static async getInitialProps({ Component, router, ctx }) {
        let pageProps = {}

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps }
    }

    render () {
        const { Component, pageProps } = this.props

        return (
            <Container>
                <ApiProvider endpoint={publicRuntimeConfig.api_endpoint}>
                    <Component {...pageProps} />
                </ApiProvider>
            </Container>
        );
    }
}
import fetch from 'unfetch'

function Api (config)
{
    const apiUrl = config.endpoint;

    async function request (url) {
        return fetch(apiUrl + '/' + url);
    };

    this.decode = async function (code) {
        const res = request('/decode?code=' + code);
        const json = await res.json();
        return json;
    }

    return this;
}

export default Api;
import React, { Component } from 'react';
import Api from '../Services/Api';

const defaultStore = null;

class ApiProvider extends React.Component
{
    state = {
        api: null
    };

    constructor (props) {
        super(props);

        this.state.api = new Api({ endpoint: props.endpoint });
    }

    render () {
        return (
            <ApiContext.Provider value={this.state.api}>
                {this.props.children}
            </ApiContext.Provider>
        );
    }
}

export const ApiContext = React.createContext(defaultStore);
export default ApiProvider;
export const ApiConsumer = ApiContext.Consumer;
export function withApi(Component) {
    return function withApiHoc(props) {
        return (
            <ApiConsumer>{ context => <Component {...props} api={context} /> }</ApiConsumer>
        )
    }
};
import React, { Component } from 'react';
import Link from 'next/link';
import { withApi } from '../Providers/ApiProvider';

class Code extends React.Component
{
    static async getInitialProps ({ query, ctx }) {
        const decodedResponse = this.props.api.decode(query.code); // Cannot read property 'api' of undefined

        return {
            code: query.code,
            decoded: decodedResponse
        };
    }

    render () {
        return (
            <div>
                [...]
            </div>
        );
    }
}

let hocCode = withApi(Code);
hocCode.getInitialProps = Code.getInitialProps;
export default hocCode;
import React,{Component}来自'React';
从“下一个/链接”导入链接;
从“../Providers/ApiProvider”导入{withApi};
类代码扩展了React.Component
{
静态异步getInitialProps({query,ctx}){
const decodedResponse=this.props.api.decode(query.code);//无法读取未定义的属性“api”
返回{
代码:query.code,
解码:解码响应
};
}
渲染(){
返回(
[...]
);
}
}
设hocCode=withApi(代码);
hocCode.getInitialProps=Code.getInitialProps;
导出默认代码;
问题是我无法访问已使用的上下文。我可以在我的
getInitialProps
中直接调用
fetch
,但是我想通过使用一个小函数来抽象它,该函数也需要一个可配置的URL


我做错了什么?

在asstatic方法
getInitialProps
中无法访问提供者的实例,它在生成反应树之前被调用(当提供者可用时)

我建议您在API模块中保存API的Singleton,并通过定期导入在
getInitialProps
方法中使用它

或者,您可以将其注入到
\u应用程序
getInitialProps中的componentPage中,类似于:

// _app.jsx
import api from './path/to/your/api.js';

export default class Webshop extends App {
    static async getInitialProps({ Component, router, ctx }) {
        let pageProps = {}
        ctx.api = api;

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps }
    }

    render () {
        const { Component, pageProps } = this.props

        return (
            <Container>
                <Component {...pageProps} />
            </Container>
        );
    }
}

// PageComponent.jsx

import React, { Component } from 'react';

class Code extends React.Component
{
    static async getInitialProps ({ query, ctx }) {
        const decodedResponse = ctx.api.decode(query.code); // Cannot read property 'api' of undefined

        return {
            code: query.code,
            decoded: decodedResponse
        };
    }

    render () {
        return (
            <div>
                [...]
            </div>
        );
    }
}

export default Code;
/\u app.jsx
将api从“/path/to/your/api.js”导入;
导出默认类Webshop扩展应用程序{
静态异步getInitialProps({Component,router,ctx}){
让pageProps={}
ctx.api=api;
if(Component.getInitialProps){
pageProps=等待组件。getInitialProps(ctx)
}
返回{pageProps}
}
渲染(){
const{Component,pageProps}=this.props
返回(
);
}
}
//PageComponent.jsx
从“React”导入React,{Component};
类代码扩展了React.Component
{
静态异步getInitialProps({query,ctx}){
const decodedResponse=ctx.api.decode(query.code);//无法读取未定义的属性“api”
返回{
代码:query.code,
解码:解码响应
};
}
渲染(){
返回(
[...]
);
}
}
导出默认代码;

这对您有意义吗?

在尝试使用
Context.Consumer
API访问功能组件中的上下文时,我遇到了类似的问题。您是否尝试过使用
static contextType=ApiContext
将其转换为类组件。这不是一个解决方案,但它将帮助您找出这是否是问题所在。问题是getInitialProps是一个静态方法,因此您无法从内部访问类实例属性it@ShubhamKhatri哦,对了。。。这太明显了。那我怎么能做这样的事呢?我需要将它作为我的HOC中getInitialProps的参数传递,对吗?这也是我尝试过的,但是我无法以编程方式访问React.Context数据,如果我使用使用者上下文包装我的组件,则无法正确调用getInitialProps。因此,您建议使用单例方法而不是React.Context?是的,singelton可以注入到我建议的所有页面组件中。这样我甚至可以只在需要的地方导入它,而不是全局注入,对吗?