TypeError: Cannot read properties of undefined (reading 'createContext')
TypeError: Cannot read properties of undefined (reading 'createContext')
大家好,我正在寻求帮助。我在使用上下文 api 将数据从一个子组件传递到另一个子组件时遇到了一些麻烦。但是我得到了这个 typeError,到目前为止我尝试了一些搜索但运气不佳。如果有人不能指出我正确的方向,将不胜感激!
谢谢
CurrencyProvider.js
import { React, Component} from 'react';
export const MContext = React.createContext('');
class CurrencyProvider extends Component {
constructor() {
super()
this.state = {
setinputValue: (value) => this.setState({ inputValue: value })
}
}
render() {
return (
<MContext.Provider value={this.state}>
{this.props.children}
</MContext.Provider>)
}
}
export default CurrencyProvider;
Dropdown.js
import { useQuery, gql } from "@apollo/client";
import { useState } from "react";
import './Dropdown.scss';
import { MContext } from "../CurrencyProvider";
const EXCHANGE_RATES = gql`
query GetExchangeRates {
rates(currency: "AUD") {
currency
rate
name
}
}
`;
function Dropdown() {
const [isToggled, setToggle] = useState(false);
const { data, loading, error } = useQuery(EXCHANGE_RATES);
if (loading) {
return <div>loading</div>;
}
if (error) {
return <div>{error}</div>;
}
return (
<div className="custom-dropdown">
<ul className={`dropdown-menu ${isToggled ? 'open':''}`}>
<li value="0" className="first-item" onClick={() => setToggle(!isToggled)} onKeyPress={() => setToggle(!isToggled)} tabIndex="0">Select Currency:</li>
{data.rates.map(({ currency, rate, name },index) => (
<MContext.Consumer>
{(context) => (
<li className="list-item" key={index} data={rate} tabIndex="0" onClick={()=>{context.setinputValue(rate)}}> <span>{name}: {currency}</span></li>
)}
</MContext.Consumer>
))}
</ul>
</div>
);
}
export default Dropdown;
Input.js
import './Input.scss';
import { MContext } from "../CurrencyProvider";
function Input() {
return(
<MContext.Consumer>
{(context) => (
<input value={context.state.inputValue} />
)}
</MContext.Consumer>
);
}
export default Input;
CurrencyContainer.js
import Dropdown from '../Dropdown/Dropdown';
import Input from '../Input/Input';
import './CurrencyContainer.scss';
import CurrencyProvider from '../CurrencyProvider';
function CurrencyContainer() {
return (
<div className='currency-container'>
<h1 >Select Items</h1>
<div className="currency-wrapper">
<CurrencyProvider>
<div><Input /></div>
<div><Dropdown /></div>
<div><Dropdown /></div>
</CurrencyProvider>
</div>
</div>
);
}
export default CurrencyContainer;
App.js
import logo from './logo.svg';
import './App.scss';
import { client } from "./ApolloClient/client";
import { ApolloProvider } from '@apollo/client';
import CurrencyContainer from './CurrencyContainer/CurrencyContainer';
function App() {
return (
<ApolloProvider client={client}>
<div className="App">
<img src={logo} className="App-logo" alt="logo" />
<CurrencyContainer />
</div>
</ApolloProvider>
);
}
export default App;
您的 React
导入不正确。将其更改为:
import React, {Component} from 'react';
React
是默认导出,不是命名导出。
React 包没有名为 React
的命名导入,它具有人们通常使用 React
的默认导入,因此您应该更改此行
import { React, Component } from 'react';
至此
import React, { Component } from 'react';
如果您使用 React 17+,则不再需要 import React from 'react';
,您可以从导入中删除对 React
的任何提及,因此您的导入将如下所示
import { createContext } from 'react';
但是您必须像这样在 .eslintrc.json
文件中关闭此导入的 lint 规则
{
"rules": {
...
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
}
}
你为什么不尝试将更多类似的东西放在一个单独的文件中 mcontext.context.jsx:
import { createContext } from "react";
const MContext = createContext('');
export default MContext;
然后就可以导入了
- 通过导入新创建的上下文、useContext 挂钩并在封装在 MContext.Provider 节点中的功能组件顶部添加类似这样的内容来获取值:
const val = useContext(MContext);
- 设置值:
<MContext.Provider value={mcontextValue}>
</MContext.Provider>
你的 MContext.Provider 节点内的所有子节点和他们的子节点都可以访问你的 MContext 值,因为我在答案的第一部分向你展示了它。
大家好,我正在寻求帮助。我在使用上下文 api 将数据从一个子组件传递到另一个子组件时遇到了一些麻烦。但是我得到了这个 typeError,到目前为止我尝试了一些搜索但运气不佳。如果有人不能指出我正确的方向,将不胜感激!
谢谢
import { React, Component} from 'react';
export const MContext = React.createContext('');
class CurrencyProvider extends Component {
constructor() {
super()
this.state = {
setinputValue: (value) => this.setState({ inputValue: value })
}
}
render() {
return (
<MContext.Provider value={this.state}>
{this.props.children}
</MContext.Provider>)
}
}
export default CurrencyProvider;
Dropdown.js
import { useQuery, gql } from "@apollo/client";
import { useState } from "react";
import './Dropdown.scss';
import { MContext } from "../CurrencyProvider";
const EXCHANGE_RATES = gql`
query GetExchangeRates {
rates(currency: "AUD") {
currency
rate
name
}
}
`;
function Dropdown() {
const [isToggled, setToggle] = useState(false);
const { data, loading, error } = useQuery(EXCHANGE_RATES);
if (loading) {
return <div>loading</div>;
}
if (error) {
return <div>{error}</div>;
}
return (
<div className="custom-dropdown">
<ul className={`dropdown-menu ${isToggled ? 'open':''}`}>
<li value="0" className="first-item" onClick={() => setToggle(!isToggled)} onKeyPress={() => setToggle(!isToggled)} tabIndex="0">Select Currency:</li>
{data.rates.map(({ currency, rate, name },index) => (
<MContext.Consumer>
{(context) => (
<li className="list-item" key={index} data={rate} tabIndex="0" onClick={()=>{context.setinputValue(rate)}}> <span>{name}: {currency}</span></li>
)}
</MContext.Consumer>
))}
</ul>
</div>
);
}
export default Dropdown;
Input.js
import './Input.scss';
import { MContext } from "../CurrencyProvider";
function Input() {
return(
<MContext.Consumer>
{(context) => (
<input value={context.state.inputValue} />
)}
</MContext.Consumer>
);
}
export default Input;
CurrencyContainer.js
import Dropdown from '../Dropdown/Dropdown';
import Input from '../Input/Input';
import './CurrencyContainer.scss';
import CurrencyProvider from '../CurrencyProvider';
function CurrencyContainer() {
return (
<div className='currency-container'>
<h1 >Select Items</h1>
<div className="currency-wrapper">
<CurrencyProvider>
<div><Input /></div>
<div><Dropdown /></div>
<div><Dropdown /></div>
</CurrencyProvider>
</div>
</div>
);
}
export default CurrencyContainer;
App.js
import logo from './logo.svg';
import './App.scss';
import { client } from "./ApolloClient/client";
import { ApolloProvider } from '@apollo/client';
import CurrencyContainer from './CurrencyContainer/CurrencyContainer';
function App() {
return (
<ApolloProvider client={client}>
<div className="App">
<img src={logo} className="App-logo" alt="logo" />
<CurrencyContainer />
</div>
</ApolloProvider>
);
}
export default App;
您的 React
导入不正确。将其更改为:
import React, {Component} from 'react';
React
是默认导出,不是命名导出。
React 包没有名为 React
的命名导入,它具有人们通常使用 React
的默认导入,因此您应该更改此行
import { React, Component } from 'react';
至此
import React, { Component } from 'react';
如果您使用 React 17+,则不再需要 import React from 'react';
,您可以从导入中删除对 React
的任何提及,因此您的导入将如下所示
import { createContext } from 'react';
但是您必须像这样在 .eslintrc.json
文件中关闭此导入的 lint 规则
{
"rules": {
...
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
}
}
你为什么不尝试将更多类似的东西放在一个单独的文件中 mcontext.context.jsx:
import { createContext } from "react";
const MContext = createContext('');
export default MContext;
然后就可以导入了
- 通过导入新创建的上下文、useContext 挂钩并在封装在 MContext.Provider 节点中的功能组件顶部添加类似这样的内容来获取值:
const val = useContext(MContext);
- 设置值:
<MContext.Provider value={mcontextValue}> </MContext.Provider>
你的 MContext.Provider 节点内的所有子节点和他们的子节点都可以访问你的 MContext 值,因为我在答案的第一部分向你展示了它。