React 上下文和 Next JS

Posted

技术标签:

【中文标题】React 上下文和 Next JS【英文标题】:React Context and Next JS 【发布时间】:2019-06-18 15:50:41 【问题描述】:

我正在尝试将简单的 React Context 添加到我的应用程序中。我在“./components/DataProvider.js”中创建了如下所示的上下文:

import React,  Component  from 'react'

const DataContext = React.createContext()

class DataProvider extends Component 
    state = 
        isAddButtonClicked: false
    

    changeAddButtonState = () => 
        if( this.state.isAddButtonClicked ) 
            this.setState(
                isAddButtonClicked: false
            )
         else 
            this.setState(
                isAddButtonClicked: true
            )            
        
    

    render() 
        return(
            <DataContext.Provider
                value=
                    isAddButtonClicked: this.state.isAddButtonClicked,
                    changeAddButtonState: () => 
                        if( this.state.isAddButtonClicked ) 
                            this.setState(
                                isAddButtonClicked: false
                            )
                         else 
                            this.setState(
                                isAddButtonClicked: true
                            )            
                        
                    
                
            >
                this.props.children
            </DataContext.Provider>
        )
    



const DataConsumer = DataContext.Consumer

export default DataProvider
export  DataConsumer 

然后我添加到“./pages/_app.js”

import App,  Container  from 'next/app'

import DataProvider from '../components/DataProvider'

class MyApp extends App 
render () 
    const  Component, pageProps  = this.props
    return (
    <Container>
        <DataProvider>
        <Component ...pageProps />
        </DataProvider>
    </Container>
    )



export default MyApp

并在“./components/AddPostButton.js”中使用它。

import React, Component from 'react'
import  DataConsumer  from './DataProvider'

import  FontAwesomeIcon  from '@fortawesome/react-fontawesome'
import  faPlus  from '@fortawesome/free-solid-svg-icons'

class AddPostButton extends Component 
    render() 
        return (
            <div>
                <DataConsumer>
                    ( changeAddButtonState ) => (
                        <a onClick=changeAddButtonState>
                            <FontAwesomeIcon icon=faPlus color='#fff' />
                        </a>
                    )
                </DataConsumer>
            </div>

        )
    



export default AddPostButton

但我收到此错误“无法读取未定义的属性 'changeAddButtonState'”。我正在使用 React 16.7 和 NextJS 7.0.2。不知道有什么问题。

第二个问题是我应该对所有内容都使用一个上下文还是只将它们用作 MVC 模式中的模型?

【问题讨论】:

我也在学习 next.js。由于我不知道为什么代码不起作用,我只是在上面尝试了您的代码(在index.js 中添加了一个AddPostButton),它似乎对我有用。在回调中使用console.log,我可以看到它正在浏览器中打印。将数据提供者更改为使用changeAddButtonState: this.changeAddButtonState 似乎也可以正常工作。这是节点:12.12.0,下一个:9.1.1,react 16.10.2,react-dom 16.10.2... 【参考方案1】:

我通过将 changeAddButtonState 移动到上下文组件状态来修复它,所以我的 DataProvider.js 现在看起来像这样

import React,  Component  from 'react'

const DataContext = React.createContext()

class DataProvider extends Component 
    state = 
        isAddButtonClicked: false,
        changeAddButtonState: () => 
            if (this.state.isAddButtonClicked) 
                this.setState(
                    isAddButtonClicked: false
                )
             else 
                this.setState(
                    isAddButtonClicked: true
                )
            
        
    

    render() 
        return(
            <DataContext.Provider
                value=this.state
            >
                this.props.children
            </DataContext.Provider>
        )
    



const DataConsumer = DataContext.Consumer

export default DataProvider
export  DataConsumer 

然后在 AddButton 组件中我将代码更改为如下所示

import React, Component from 'react'
import  DataConsumer  from './DataProvider'

import  FontAwesomeIcon  from '@fortawesome/react-fontawesome'
import  faPlus  from '@fortawesome/free-solid-svg-icons'

class AddPostButton extends Component 
    constructor(props) 
        super(props)
    

    render() 
        return (
            <div>
                <DataConsumer>
                    (context) => (
                        <a onClick=context.changeAddButtonState>
                            <FontAwesomeIcon icon=faPlus color='#fff' />
                        </a>
                    )
                </DataConsumer>
            </div>

        )
    



export default AddPostButton

【讨论】:

以上是关于React 上下文和 Next JS的主要内容,如果未能解决你的问题,请参考以下文章

检索数据服务器端并使用 Next.js 保存在上下文中

基于nextJS的React 服务端渲染

React.useContext() 不断返回未定义?

如何在 Next.js 中设置全局上下文而不会出现“文本内容不匹配”错误?

Next.js 上下文提供程序用页面特定布局组件包装 App 组件,提供未定义的数据

使用上下文 API (React.js) 仅更改状态对象中的特定键