【问题标题】:React 16.3 Context API -- Provider/Consumer issuesReact 16.3 上下文 API——提供者/消费者问题
【发布时间】:2018-04-07 15:14:00
【问题描述】:

我一直在做一些关于 React 16.3.1 ContextAPI 的实验。我遇到了一些我无法理解的事情。我希望我能得到你的帮助。

注意:问题已解决,但不是我正在寻找的解决方案。

让我们开始对同一文件中的多个组件进行第一次实验 Index.js

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();

class AppProvider extends Component {
  state = {
    name: 'Superman',
    age: 100
  };

  render() {
    const increaseAge = () => {
      this.setState({ age: this.state.age + 1 });
    };

    const decreaseAge = () => {
      this.setState({ age: this.state.age - 1 });
    };
    return (
      <Provider
        value={{
          state: this.state,
          increaseAge,
          decreaseAge
        }}
      >
        {this.props.children}
      </Provider>
    );
  }
}

class Person extends Component {
  render() {
    return (
      <div className="person">
        <Consumer>
          {context => (
            <div>
              <p>I'm {context.state.name}</p>
              <p>I'm {context.state.age}</p>
              <button onClick={context.increaseAge}>
                <span>+</span>
              </button>
              <button onClick={context.decreaseAge}>
                <span>-</span>
              </button>
            </div>
          )}
        </Consumer>
      </div>
    );
  }
}

class App extends Component {
  render() {
      return (
        <AppProvider>
          <div className="App">
            <p>Imma Apps</p>
            <Person />
          </div>
        </AppProvider>
      );
    }
  }

export default App;

结果,这渲染完美,没有任何错误。我可以看到姓名(超人)和年龄(100)。我可以将年龄增加和减少 1。

如您所见,我从 react 导入了 {createContext},然后创建了 {Provider, Consumer}。用状态值和&lt;Consumer&gt; 包裹&lt;Provider&gt;

下一个实验,是从 index.js 中精确复制每个组件并将它们分别粘贴到自己的文件中。

AppProvider.js

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();

class AppProvider extends Component {
  state = {
    name: 'Superman',
    age: 100
  };

  render() {
    const increaseAge = () => {
      this.setState({ age: this.state.age + 1 });
    };

    const decreaseAge = () => {
      this.setState({ age: this.state.age - 1 });
    };
    return (
      <Provider
        value={{
          state: this.state,
          increaseAge,
          decreaseAge
        }}
      >
        {this.props.children}
      </Provider>
    );
  }
}
export default AppProvider;

Person.js

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();

class Person extends Component {
  render() {
    return (
      <div className="person">
        <Consumer>
          {context => (
            <div>
              <p>I'm {context.state.name}</p>
              <p>I'm {context.state.age}</p>
              <button onClick={context.increaseAge}>
                <span>+</span>
              </button>
              <button onClick={context.decreaseAge}>
                <span>-</span>
              </button>
            </div>
          )}
        </Consumer>
      </div>
    );
  }
}
export default Person;

App.js

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();

class App extends Component {
  render() {
      return (
        <AppProvider>
          <div className="App">
            <p>Imma Apps</p>
            <Person />
          </div>
        </AppProvider>
      );
    }
  }

export default App;

因此,我收到错误 - TypeError: Cannot read property 'state' of undefined

我无法掌握确切的错误是什么。我所做的只是将每个错误复制并粘贴到文件中,而不更改任何语法。

虽然,替代方法是创建一个新文件并添加以下语法...

Context.js

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

然后进入每个文件(AppProvider.jsPerson.jsApp.js)并替换...

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();'

...进入...

import Context from './Context.js';。还将... &lt;Provider&gt; 替换为 &lt;Context.Provider&gt;&lt;Consumer&gt; 替换为 &lt;Context.Consumer&gt;

这消除了错误。但是,这不是我正在寻找的解决方案。我想使用&lt;Provider&gt; 标签而不是&lt;Context.Provider&gt;

问题是,为什么会出现此错误?

为什么我无法使用这个方法...

import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();'

对于单独文件中的每个组件,我可以使用&lt;Provider&gt; 标签?

有什么办法可以得到我正在寻找的解决方案吗?

感谢您的帮助,并提前致谢。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您收到 TypeError: Cannot read property 'state' of undefined. 因为每次调用const { Provider, Consumer } = createContext(); 时都会创建一个新对象,因此需要导出该对象以供消费者使用此特定对象。

    所以在 person.js 中 当您尝试执行 {context.state.age} 时,它确实没有此对象的状态,您只是创建了一个新的 Context,它是空的,或者更确切地说是 React 内部方法和属性。

    所以为了使用同一个对象只需导出它,就像您在 Context.js 中所做的那样,而不是这样做:

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

    替换为:

    import { createContext } from 'react';
    const { Provider, Consumer } = createContext();
    export { Consumer, Provider };
    

    然后当你想在其他文件中使用它(意味着导入它)只需调用:

    import { Consumer, Provider } from './Context.js';
    

    【讨论】:

    • 感谢您的帮助...它成功了。除了需要修复export { Consumer, Provider };
    • @sirrus 当然,很高兴为您提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 2014-05-22
    • 1970-01-01
    • 2023-03-21
    • 2018-11-03
    相关资源
    最近更新 更多