Next.JS-getInitialProps通过ContextProvider将道具和状态传递给子组件

时间:2019-03-21 22:03:43

标签: javascript reactjs next.js

我正在getInitialProps()中使用_App.js来获取一些api数据,我想将该数据作为道具通过React Context传递给我的其他组件。我想通过构造函数使用状态初始化Context Provider。

首先,我通过createContext()初始化上下文。

config/Context.js

import { createContext } from 'react';
const Context = createContext();
export default Context;

然后,我使用构造函数在其自己的组件中创建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;
 

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

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>
    );
  }
}

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

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;

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

此处正在回购该问题:https://github.com/joelhoelting/next-context-api-test

1 个答案:

答案 0 :(得分:1)

ContextProvider.js中,您忘记将value传递给Context.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;
相关问题