Next.JS -- getInitialProps 通过 ContextProvider 将 props 和 state 传递给子组件

Joe*_*ing 4 javascript reactjs next.js

我正在使用getInitialProps()in_App.js来获取一些 api 数据,并且我想通过 React Context 将该数据作为道具传递给我的其他组件。我想通过构造函数用状态初始化上下文提供程序。

首先我通过createContext().

config/Context.js

import { createContext } from 'react';
const Context = createContext();
export default Context;
Run Code Online (Sandbox Code Playgroud)

然后我使用构造函数在它自己的组件中创建 Context.Provider 来初始化状态。

provider/ContextProvider.js

import React, { Component } from 'react';
import Context from '../config/Context';

class ContextProvider extends Component {
  constructor(props) {
    super(props);
    
    this.state = {
      filters: {
        active: true,
        headerActive: false
      }
    };
  }

  render() {
    return (
      <Context.Provider>
        {this.props.children}
      </Context.Provider>
    );
  }
}

export default ContextProvider;
Run Code Online (Sandbox Code Playgroud)

_app.js我内部进行 API 调用getInitialProps()并将该数据传递到上下文提供程序中。

pages/_app.js

import App, { Container } from 'next/app';
import ContextProvider from '../provider/ContextProvider';
import fetch from 'isomorphic-unfetch';

export default class MyApp extends App {
  static async getInitialProps() {
    const res = await fetch('https://node-hnapi.herokuapp.com/news');
    let data = await res.json();

    console.log(data)
    return { articles: data }
  }

  render () {
    const { Component, pageProps } = this.props;
    
    return (
      <Container>
        <ContextProvider value={{ articles: this.props.articles}}>
          <Component {...pageProps} />
        </ContextProvider>
      </Container>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在这一点上,我假设我可以通过Context.Consumer或类似的钩子访问上下文,useContext()但上下文在以下组件中未定义:

components/ArticleList.js

import React from 'react';
import Context from '../config/Context';

const ArticleList = () => {
  const generateArticles = () => {
    const context = React.useContext(Context);
    console.log(context, 'context') // Context is undefined here
    // return context.articles.map(article => <p>{article.title}</p>)
    // Error: Cannot read property 'articles' because context is undefined
  }

  return (
    <div>
      <h3>Article List</h3>
      {generateArticles()}
    </div>
  );
};

export default ArticleList;
Run Code Online (Sandbox Code Playgroud)

为什么在 中未定义上下文components/ArticleList.js?我尝试通过将上下文传递到组件中Context.Consumer,但得到了相同的结果。

这是复制问题的回购:https : //github.com/joelhoelting/next-context-api-test

evg*_*tia 7

ContextProvider.js你忘记传递valueContext.Provider

import React, { Component } from 'react';
import Context from '../config/Context';

class ContextProvider extends Component {
  constructor(props) {
    super(props);

    this.state = {
      filters: {
        active: true,
        headerActive: false
      }
    };
  }

  render() {
    const { value } = this.props
    return (
      <Context.Provider value={ value }>
        {this.props.children}
      </Context.Provider>
    );
  }
}

export default ContextProvider;
Run Code Online (Sandbox Code Playgroud)