类型错误:无法读取未定义的属性(读取“createContext”)

jor*_*dan 5 javascript reactjs react-context react-hooks

嘿,我正在寻求帮助。我在使用上下文 api 将数据从一个子组件传递到另一个子组件时遇到一些问题。但我得到了这个 typeError ,到目前为止我尝试了一些搜索,但运气不佳。如果有人不能指出我正确的方向,我将不胜感激!

谢谢

在此输入图像描述 货币提供者.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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

输入.js

import './Input.scss';
import { MContext } from "../CurrencyProvider";

function Input() {
    return(
        <MContext.Consumer>
            {(context) => (
                <input value={context.state.inputValue} />
            )}
        </MContext.Consumer>
    );
}

export default Input;
Run Code Online (Sandbox Code Playgroud)

货币容器.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;
Run Code Online (Sandbox Code Playgroud)

应用程序.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;
Run Code Online (Sandbox Code Playgroud)

小智 6

为什么不尝试在单独的文件 mcontext.context.jsx 中放置更多类似的内容:

import { createContext } from "react";

const MContext = createContext('');

export default MContext;
Run Code Online (Sandbox Code Playgroud)

然后你可以导入它并

  • 通过导入新创建的上下文、useContext 挂钩并将类似的内容添加到封装在 MContext.Provider 节点内的功能组件的顶部来获取值:
const val = useContext(MContext);
Run Code Online (Sandbox Code Playgroud)
  • 设定值:
<MContext.Provider value={mcontextValue}>

</MContext.Provider>
Run Code Online (Sandbox Code Playgroud)

MContext.Provider 节点内的所有子节点及其子节点都可以访问您的 MContext 值,只要您获得它,就像我在答案的第一部分中向您展示的那样。