我一直在 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。
如你所见,我导入了{createContext}
从 react 然后创建 {Provider, Consumer}
.包裹<Provider>
状态值和 <Consumer>
.
下一个实验,是从 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。
我无法理解确切的错误是什么。我所做的只是将每个错误复制并粘贴到文件中,而不更改任何语法。
虽然,替代方法是创建一个新文件并添加以下语法...
上下文.js
import { createContext } from 'react';
const Context = createContext();
export default Context;
然后进入每个文件(AppProvider.js。Person.js 和App.js)并替换...
import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();
'
...进入...
import Context from './Context.js';
.也替换... <Provider>
进入<Context.Provider>
和 <Consumer>
进入<Context.Consumer>
.
这消除了错误。但是,这不是我正在寻找的解决方案。我想用 <Provider>
标记而不是 <Context.Provider>
.
问题是,为什么会出现此错误?
为什么我不能使用这个方法...
import React, { Component, createContext } from 'react';
const { Provider, Consumer } = createContext();
'
对于单独文件中的每个组件,所以我可以使用 <Provider>
标签 ?
是否有任何方法可以获得我正在寻找的解决方案?
感谢您的帮助,在此先致谢。
最佳答案
您遇到了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';
关于javascript - React 16.3 Context API——提供者/消费者问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49708792/