首页 > 解决方案 > React:如何将数据从 getInitialProps 传递到 Context API?

问题描述

我目前面临一个问题,即更新我使用从获取的数据中获取的结果创建的上下文getInitialProps

我一直在undefined争取StateContext

代码沙箱

我的逻辑是:

  1. 创建一个StateContext空状态。
  2. 获取初始数据/page/_app.js,更新StateContext
  3. 使用反应钩子显示组件StateContext中的更新TopPost.js

另一个问题:我认为我的 fetch 很好,但我不确定。

这是我的状态上下文:

import React, { createContext, Component } from 'react'

const StateContext = createContext();

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

        this.state = {
            top_posts: null,
            summary_metrics: null
        };
    }

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

export default StateProvider;

然后我在这里获取初始数据/page/_app/js

import "../styles/main.css";
import fetch from 'isomorphic-unfetch';
import App from 'next/app';
import StateProvider from '../components/contexts/StateContext';
import { AuthProvider } from '../components/contexts/AuthContext';

export default class MyApp extends App {
    static async getInitialProps() {
        try {
            const [data1, data2] = await Promise.all([
                fetch('https://www.mocky.io/v2/5ecefb253200006800e3ce8d'),
                fetch('https://www.mocky.io/v2/5ed071f73500007300ff9c38'),
            ])

            let top_post = data1
            let summary_metrics = data2

            console.log("top_post", top_post);
            console.log("summary_metrics", summary_metrics);

            return { 
                top_post: top_post,
                summary_metrics: summary_metrics
             }
        } catch (err) {
            console.log(err);
        }      
    }

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

        return (
            <AuthProvider> 
                <StateProvider value={{ top_post: this.top_post, summary_metrics: this.summary_metrics }}>
                    <Component {...pageProps} />
                </StateProvider>
            </AuthProvider>
        );
    }
}

在此处使用获取的数据:

import moment from 'moment'
import React, { useState, useEffect, useContext } from "react";
import { BsArrowUpRight } from 'react-icons/bs';

import StateContext from "../contexts/StateContext";

const TopPost =()=> {
    const [posts, setPosts] = useState([]);

    const context = useContext(StateContext);
    console.log('State context:', context) // Context is undefined here

    return (
        <div>
            <div className="min-w-0 max-h-screen overflow-y-scroll">
                {posts.map(post => (
                <div key={post.id}>
                        <div className='px-10 my-4 py-4 bg-white border border-8 border-gray-400 rounded-lg border-solid'>
                            <div className='flex justify-between'>
                                <span className='font-light text-black text-lg font-semibold'>@{post.username}</span>
                                <span className='font-medium rounded ml-56'> {moment(post.postDate).format(('L'))}. {moment(post.postDate).format(('LT'))}</span>
                                <a className="font-extrabold rounded text-3xl text-blue-600" href={post.postUrl} target="_blank" rel="noopener noreferrer">
                                    <BsArrowUpRight />
                                </a>
                            </div>

                            <div className="mt-2">
                                <p className='mt-2 text-xl text-gray-600'>{post.textContent}</p>
                            </div>
                        </div>
                </div>
              ))}
              </div>
            </div>
    );
}
export default TopPost;

标签: reactjsreact-hooksreact-context

解决方案


你可以试试通过this.propsMyApp

 <StateProvider value={{ ...this.props }}>
  <Component {...pageProps} />
 </StateProvider>

我也认为你应该改变value道具StateProvider

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

- 编辑

我注意到的事情

确保您使用的是默认导入

import fetch from "isomorphic-unfetch";

响应必须转换为 json

 const [data1, data2] = await Promise.all([                
    fetch('https://www.mocky.io/v2/5ecefb253200006800e3ce8d').then(response => response.json()),                
    fetch('https://www.mocky.io/v2/5ed071f73500007300ff9c38').then(response => response.json()),
])

即使你修复了这些东西,你也会得到

Cannot read property 'pathname' of undefined

现在我不知道它是由沙箱引起的还是代码中存在其他问题。


推荐阅读