TypeError: (0, _react.useEffect) कोई फ़ंक्शन नहीं है


10

जब विकास के माहौल में, मेरा ऐप ठीक काम करता है। जब उत्पादन वातावरण में यह त्रुटि के साथ क्रैश होता है:

Uncaught TypeError: (0 , _react.useEffect) is not a function

यह मेरे द्वारा बनाई गई फ़ाइल में होता है जहां मैं प्रतिक्रिया और आयात का उपयोग करता हूं जैसे:

import React, { useEffect } from 'react'

const X = () => {
  useEffect(() => { ... })

  ...
}

इस लाइन के ठीक नीचे एक कंसोल.लॉग जोड़ना इस बात की पुष्टि करता है कि उत्पादन में और उपयोग होने पर अपेक्षित फ़ंक्शन वास्तव में उपयोग होने पर वास्तव में अपरिभाषित है।

मैंने किसी भी प्रतिक्रिया या रिएक्शन-डोम संस्करण के लिए अपना पैकेज.जसन, यार्न ।लॉक और नोड_मॉडल्स की जाँच की, जो कि 16.8.0 से कम हो सकता है, जहाँ यूज़फेक्ट पेश किया गया था। लेकिन सब कुछ 16.13.1 है और वे मुख्य निर्भरता हैं और मैंने अपने यार्न कैश को साफ करने, नोड_मॉड्यूल और यार्न को हटाने, और फिर से स्थापित करने का प्रयास किया।

मैंने इसे peerDependenciesसफलता के बिना जोड़ने और हटाने की कोशिश की ।

मैंने यह सुनिश्चित करने के लिए एक जांच में लगाया कि रिएक्ट के 2 अलग-अलग संस्करण नहीं चल रहे हैं, लेकिन window.React1 = Reactलाइब्रेरी के window.React2 = Reactअंदर और मेरे आवेदन के अंदर बचत करना और जांचना

window.React1 === window.React2 यह सच था, इसलिए यह भी नहीं है।

अंत में, मैंने भी नोड_मॉड्यूल्स में विशिष्ट एक को रिएक्ट करने की कोशिश की, लेकिन बिना किसी भाग्य के।

एकमात्र समाधान मैंने पाया है कि अगर मैं इसे आयात करता हूं तो यह काम करता है:

import React from 'react';

const X = () => {
  React.useEffect(() => { ... })
  ...
}

लेकिन यह बिल्कुल विनाशकारी आयात का उपयोग करने के समान होना चाहिए? अगर मैं स्पष्ट रूप से React.useEffect का उपयोग करता हूं तो यह मुझे अपने सभी अन्य उपयोग को बदलने के लिए बाध्य करता है और उपयोग करने के लिए हुक का उपयोग करता है React.useSateऔरReact.useEffect

अगली त्रुटि बस बन जाती है: TypeError: (0 , _react.useState) is not a functionएक अन्य फ़ाइल में जहां मैं रिएक्ट हुक का उपयोग करता हूं।

मैं समस्या को हल करने के लिए एक समाधान लागू नहीं करना चाहते हैं।

मैं microbundleरिएक्ट का उपयोग करके अपने पुस्तकालय को बंडल करने के लिए उपयोग करता हूं। मैं parcel-bundlerरिएक्ट-कंपोनेंट को इम्पोर्ट करने के लिए इस्तेमाल करता हूं और इसे देव माहौल में (सीधे src से) या ठेस (बंडल किए गए लाइब्रेरी) में रेंडर करता हूं

मेरे द्वारा उपयोग किए गए बंडल संस्करण को .mjs के साथ बंडल किया गया है

मैंने minified .mjs बंडल के आउटपुट की जाँच की और अंदर React को इस तरह आयात किया गया है:

import ue,{useEffect as pe,useState as fe}from"react";

जो मुझे ठीक लगता है।

मुझे वास्तव में समझ में नहीं आता है कि एक पुनर्गठित आयात इसे कैसे तोड़ देगा, लेकिन सिर्फ React.useEffect करने से काम ठीक हो जाएगा?

यहाँ मेरा पैकेज है

{
  "name": "xxx",
  "version": "1.1.4",
  "repository": "git@github.com:xxx/xxx.git",
  "author": "xxx",
  "license": "MIT",
  "source": "src/index.ts",
  "main": "dist/bundle.js",
  "umd:main": "dist/bundle.umd.js",
  "module": "dist/bundle.mjs",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/@xxx"
  },
  "scripts": {
    "build": "microbundle",
    "dev": "parcel ./test-app/dev/index.html --port 3000",
    "start": "parcel ./test-app/serve/index.html --port 3000",
    "storybook": "start-storybook -s ./public -c .storybook --ci",
    "prepublishOnly": "yarn build"
  },
  "dependencies": {
    "@api-platform/admin": "2.1.0",
    "@api-platform/api-doc-parser": "0.8.2",
    "@fortawesome/fontawesome-svg-core": "^1.2.28",
    "@fortawesome/free-solid-svg-icons": "^5.13.0",
    "@fortawesome/react-fontawesome": "^0.1.9",
    "@material-ui/core": "^4.9.10",
    "@material-ui/icons": "^4.9.1",
    "@react-keycloak/web": "^2.1.1",
    "@types/pluralize": "^0.0.29",
    "google-geocoder": "0.2.1",
    "history": "^4.10.1",
    "keycloak-js": "^9.0.3",
    "lodash.debounce": "^4.0.8",
    "lodash.omit": "^4.5.0",
    "lodash.set": "4.3.2",
    "notistack": "0.9.9",
    "papaparse": "^5.2.0",
    "parcel-bundler": "1.12.4",
    "polished": "^3.5.2",
    "react": "16.13.1",
    "react-admin": "3.4.1",
    "react-dom": "16.13.1",
    "react-is": "16.13.1",
    "react-redux": "^7.2.0",
    "recompose": "^0.30.0",
    "redux": "4.0.5",
    "styled-components": "5.1.0"
  },
  "devDependencies": {
    "@babel/core": "7.9.0",
    "@babel/plugin-syntax-export-default-from": "7.8.3",
    "@babel/preset-env": "7.9.5",
    "@babel/preset-react": "7.9.4",
    "@storybook/addon-a11y": "5.3.18",
    "@storybook/addon-actions": "5.3.18",
    "@storybook/addon-info": "5.3.18",
    "@storybook/addon-knobs": "5.3.18",
    "@storybook/addon-links": "5.3.18",
    "@storybook/addon-storyshots": "5.3.18",
    "@storybook/addon-storysource": "5.3.18",
    "@storybook/addon-viewport": "5.3.18",
    "@storybook/react": "5.3.18",
    "@testing-library/react": "^10.0.3",
    "@types/jsonld": "1.5.1",
    "@types/lodash": "4.14.149",
    "@types/node": "13.11.1",
    "@types/papaparse": "5.0.3",
    "@types/react-redux": "7.1.7",
    "@types/recompose": "^0.30.7",
    "@types/styled-components": "5.1.0",
    "@welldone-software/why-did-you-render": "4.0.7",
    "awesome-typescript-loader": "5.2.1",
    "babel-loader": "^8.1.0",
    "babel-plugin-module-resolver": "4.0.0",
    "babel-plugin-styled-components": "1.10.7",
    "lodash.get": "4.4.2",
    "lodash.uniq": "4.5.0",
    "microbundle": "0.11.0",
    "openapi-types": "1.3.5",
    "parcel-plugin-static-files-copy": "2.3.1",
    "pluralize": "^8.0.0"
  },
  "alias": {
    "jsonld": "./node_modules/jsonld/dist/jsonld.js"
  },
  "staticFiles": {
    "staticPath": "public",
    "watcherGlob": "**"
  }
}

यह भी ध्यान देने योग्य है, यह केवल रिएक्ट है जिसके साथ मुझे यह समस्या हो रही है। मेरे सभी अन्य पुनर्गठित आयात ठीक काम करते हैं।


डिफ़ॉल्ट आयात के सदस्यों को संदर्भित करने के रूप में किसी भी तरह से नाम आयात का उपयोग करना। मेरा अनुमान है कि, विकास के समय पर, आपके पास कुछ अतिरिक्त लोडर हैं जो मॉड्यूल लोडर के बीच विरासत संगतता मुद्दों के आसपास काम करने के लिए कुछ शेंनिगन कर रहे हैं
अलुअन हदद

1
क्या आप globalध्वज की कोशिश कर सकते हैं --globals react=Reactऔर प्रतिक्रिया को सहकर्मी निर्भरता के रूप में जोड़ सकते हैं <- हालांकि यह एक उचित निर्धारण नहीं हो सकता है। इस मुद्दे को देखें: github.com/developit/microbundle/issues/537 यह ऐसा लग रहा है जैसे किyarn
जी मोक

1
क्या आप यह देखने के लिए कि क्या वह काम करता है, क्या आप माइक्रोबंडल @ स्थापित करने का प्रयास कर सकते हैं? बस यह जांचने के लिए कि क्या यह वास्तव में वर्तमान माइक्रोबंडल संस्करण मुद्दा है
जी मोक

यदि आप टाइपस्क्रिप्ट का उपयोग कर रहे हैं, तो आप इस मुद्दे पर भी गौर कर सकते हैं: github.com/developit/microbundle/issues/564
जी मोक

1
मेरा अनुमान है कि यह उत्पादन के निर्माण के microbundlerबजाय उपयोग करने के कारण हुआ है react-scripts, या एक खराब तरीके से कुछ बदल बंडलर कॉन्फ़िगरेशन। मैं आपका ध्यान आकर्षित करना चाहता हूं प्रतिक्रियाएं हुक नाम के साथ शुरू होनी चाहिए useऔर इस पंक्ति में हो सकती हैं import ue,{useEffect as pe,useState as fe}from"react";जो आयात का उपयोग करती हैं क्योंकि peप्रतिक्रिया में कुछ गलत हो गया था। तो, क्या आपने create-react-appऔर बनाने की कोशिश की थी react-scripts?
मकन

जवाबों:


4

ऐसा लगता है कि microbundlerरिएक्ट बर्दाश्त नहीं होता। यह एक बंडल बनाता है जो reactवैश्विक दायरे से उपयोग करने का प्रयास करता है , बजाय इसके Reactकि वास्तव में उजागर हो।

उसी कारण से आपका वर्कअराउंड React.useEffectअपेक्षा के अनुरूप काम करता है, बस कल्पना करें कि यह कैसा दिखता है window.React.useEffect

यहाँ एक आदिम अनुप्रयोग का एक उदाहरण दिया गया है:

import ReactDOM from 'react-dom';
import React, { useEffect, useState } from 'react';

/**
 * necessary workaround, microbundle use `h` pragma by default,
 * that undefined when use React
 * another option is to make build with option --jsx
 * @example microbundle --globals react=React --jsx React.createElement
 * yes, yet another workaround
*/
window.h = React.createElement;

const X = () => {
  const [A, B] = useState('world');

  useEffect(() => {
    B('MLyck');
  }, [])

  return `Hello ${A}`;
}

ReactDOM.render(<X />, document.querySelector('react-app'));

बस के साथ बंडल के बाद microbundleयह पूरी तरह से टूट गया, लेकिन जब आप के साथ बंडल करने की कोशिश करते हैं

microbundle --globals react=React

जैसा कि सही ढंग से @Jee मोक का सुझाव है, यह सही बंडल का उत्पादन करेगा। मुझे उम्मीद है कि टिप्पणियां बताएंगी कि क्या हुआ।

!function (e, t) {
  "object" == typeof exports && "undefined" != typeof module ?
    t(require("react-dom"), require("react")) :
    "function" == typeof define && define.amd ?
      define(["react-dom", "react"], t) :
      t(e.ReactDOM, e.React);
  /*
  String above is core of problem,
  in case you try to bundle without options `--globals react=React`
  it will looks like: `t(e.ReactDOM, e.react);`
  Obviously `react` is not defined in `e` e.g. `this` e.g. `window`
  due to react expose self as `React`
   */
}(this, function (e, t) {
  e = e && e.hasOwnProperty("default") ? e.default : e, window.h = ("default" in t ? t.default : t).createElement, e.render(h(function () {
    var e = t.useState("world"), n = e[0], r = e[1];
    return t.useEffect(function () {
      r("MLyck");
    }, []), "Hello " + n;
  }, null), document.querySelector("react-app"));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.development.js"></script>

    <react-app></react-app>

और, वैसे, "पुनर्गठन आयात" दोष के लिए बिल्कुल नहीं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.