【问题标题】:TypeError: Cannot read properties of undefined (reading 'createContext')TypeError:无法读取未定义的属性(读取“createContext”)
【发布时间】:2021-11-24 01:42:38
【问题描述】:

大家好,我正在寻求帮助。我在使用上下文 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;

【问题讨论】:

    标签: javascript reactjs react-hooks react-context


    【解决方案1】:

    您为什么不尝试在单独的文件 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 值,只要您得到它,正如我在答案的第一部分中向您展示的那样。

    【讨论】:

      【解决方案2】:

      您的React 导入不正确。将其更改为:

      import React, {Component} from 'react';
      

      React 是默认导出,而不是命名导出。

      【讨论】:

        【解决方案3】:

        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"
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-26
          • 2021-12-20
          • 2021-11-27
          • 2022-01-21
          • 2021-12-04
          • 2021-12-09
          • 2021-12-06
          • 2022-01-13
          相关资源
          最近更新 更多