反应上下文和单独的类

Cra*_*aig 7 javascript reactjs

我放弃了对Redux(我是React的新手)的希望,并且看到反过来的Alpha版本提供了一个新的Context.

所以我试图学习它,我的目标是,我有一个Navbar,我想在我的上下文中响应一个状态,{isAuthorised: false}.

我正在关注这些家伙的视频:

但他所有的代码都在一个文件中.我正在努力做到'正确'.

我所做的是创建了一个名为"context"的文件夹,并在其中创建了一个名为provider.jsx的jsx.

import React, {Component} from 'react';


export default class MyProvider extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isAuthenticated: false
        }
    }

    render() {
        const MyContext = React.createContext();
        return(
            <MyContext.Provider value="Test Text">
                {this.props.children}
            </MyContext.Provider>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/context/provider.jsx

在那里,我在渲染中创建了上下文(这可能是错的......也许这意味着在我的App jsx中发生?).

我在那里创建了一个状态,默认是被认为是假的.(我稍后会添加代码以将其设置为应该是什么).

这编译...并运行.

在我的App组件中,我使用我的提供程序,如下所示:

import MyProvider from './context/provider.jsx';


export default class App extends Component {

    render() {
        return (
            <MyProvider>
            <div>
                <Router>
                    <div>
                    <Navbar />
                        <Route exact path='/' component={Home}  />
                        <Route path='/about' component={About} />
Run Code Online (Sandbox Code Playgroud)

https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/app.jsx

所以我用MyProvider包装了所有代码.

在我的Navbar组件中,我导入了我的提供程序:

import MyProvider from '../../context/provider.jsx';
Run Code Online (Sandbox Code Playgroud)

然后我尝试在我的渲染中从我的提供者输出somethign:

     return (
    <div>
         <MyProvider.Consumer>
            {(context)=> (
                <p>Here I am {context}</p>
            )}
        </MyProvider.Consumer> 
    <nav className="navbar navbar-expand">
Run Code Online (Sandbox Code Playgroud)

https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/components/navbar/navbar.jsx

但这对我来说非常糟糕.

警告:React.createElement:type无效 - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:undefined.您可能忘记从其定义的文件中导出组件,或者您可能混淆了默认导入和命名导入.

检查渲染方法Navbar.在div中的Navbar(由App创建)(由App创建)

未捕获的错误:元素类型无效:期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:undefined.您可能忘记从其定义的文件中导出组件,或者您可能混淆了默认导入和命名导入.

我怎样才能让它发挥作用?我的.createContext应该驻留在哪里?

代码(有错误)在这里.

Tom*_*zyk 5

所以问题是你导出MyProvider并尝试访问它上面的静态组件 - 这是undefined:

console.log(MyProvider.Consumer);  // undefined
Run Code Online (Sandbox Code Playgroud)

作为组件中Consumer的静态属性存在.MyContext

你需要改变什么:

provider.jsx

import React, {Component} from 'react';

export const MyContext = React.createContext();

export default class MyProvider extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isAuthenticated: false
        }
    }

    render() {

        return(
            <MyContext.Provider value={this.state.isAuthenticated}>
                {this.props.children}
            </MyContext.Provider>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在navbar.jsx中

import MyProvider, { MyContext } from '../../context/provider.jsx';

<MyProvider>
   <MyContext.Consumer>
      {(context)=> (
          <p>Here I am {context}</p>
      )}
   </MyContext.Consumer> 
</MyProvider>
Run Code Online (Sandbox Code Playgroud)

看看这个教程.

编辑:

为了让你Consumer存在,MyProvider你必须在其上分配指向MyContext的静态变量Consumer

MyProvider.Consumer = MyContext.Consumer;
Run Code Online (Sandbox Code Playgroud)

然后我认为你可以使用它:

<MyProvider>
   <MyProvider.Consumer>
      {(context)=> (
          <p>Here I am {context}</p>
      )}
   </MyProvider.Consumer> 
</MyProvider>
Run Code Online (Sandbox Code Playgroud)

但是我不确定这是不是一个好主意.