gpt4 book ai didi

javascript - 使用 HOC 在 Next.js getInitialProps 中访问使用的 React.Context

转载 作者:行者123 更新时间:2023-12-01 16:10:53 25 4
gpt4 key购买 nike

我试图通过使用一个简单的服务来抽象我的 API 调用,该服务提供了一个非常简单的方法,这只是一个 HTTP 调用。我将此实现存储在 React 上下文中,并在我的 _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>
);
}
}

服务/Api.js
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;

提供者/ApiProvider.js
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>
)
}
};

页面/code.js
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;

问题是我无法访问使用的上下文。我可以直接发 fetch调用我的 getInitialProps ,但是我想通过使用一个小函数来抽象它,该函数也需要一个可配置的 URL。

我究竟做错了什么?

最佳答案

您无法以 的身份访问您的提供者的实例静态 方法getInitialProps ,它在 React 树生成之前被调用(当你的提供者可用时)。

我建议你保存一个 辛格尔顿 在 API 模块中使用您的 API,并在 getInitialProps 中使用它通过常规导入的方法。

或者,您可以将其注入(inject)到 _app 内的 componentPage 中。 getInitialProps,类似这样的东西:

// _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;

这对你有意义吗?

关于javascript - 使用 HOC 在 Next.js getInitialProps 中访问使用的 React.Context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54709299/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com