我一直在对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}
,然后创建{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:无法读取未定义的属性'state'。
我无法理解确切的错误是什么。我所做的只是将每个文件复制并粘贴到文件中而不更改任何语法。
虽然,替代方法是创建一个新文件并添加语法......
Context.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();
“
... INTO ...
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>
标记吗?
有什么方法可以获得我正在寻找的解决方案吗?
感谢您的帮助,并提前致谢。
答案 0 :(得分:4)
您的 TypeError:无法读取未定义的属性“状态”。
因为每次调用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';