LoạiError: (0, _react.useEffect) không phải là một hàm


9

Khi trong môi trường phát triển, ứng dụng của tôi hoạt động tốt. Khi trong môi trường sản xuất, nó gặp sự cố với lỗi:

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

Nó xảy ra trong một tệp tôi đã tạo khi tôi nhập React và useEffect như vậy:

import React, { useEffect } from 'react'

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

  ...
}

thêm một console.log ngay bên dưới dòng này xác nhận rằng useEffect thực sự không được xác định khi sản xuất và chức năng mong đợi khi ở dev.

Tôi đã kiểm tra gói.json, Sợi.lock & node_modules của mình xem có phiên bản phản ứng hoặc phản ứng-dom nào có thể dưới 16.8.0 hay không khi giới thiệu useEffect được giới thiệu. Nhưng tất cả mọi thứ là 16.13.1 và chúng là phần phụ thuộc chính và tôi đã cố gắng làm sạch bộ đệm sợi của mình, xóa node_modules & Sợi.lock và cài đặt lại.

Tôi đã thử thêm và xóa nó khỏi peerDependenciesmà không thành công.

Tôi đã kiểm tra để đảm bảo không có 2 phiên bản React riêng biệt đang chạy, nhưng lưu window.React1 = Reacttrong thư viện và window.React2 = Reactbên trong ứng dụng của tôi và kiểm tra

window.React1 === window.React2 Đó là sự thật, vì vậy đó cũng không phải là nó.

Cuối cùng, tôi cũng đã cố gắng đặt bí danh React cho một cái cụ thể trong node_modules, nhưng không gặp may mắn.

Giải pháp duy nhất tôi thấy có hiệu quả là nếu tôi nhập nó như vậy:

import React from 'react';

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

Nhưng điều này có nên giống hệt như sử dụng nhập khẩu bị phá hủy? Nếu tôi sử dụng React.useEffect một cách rõ ràng, nó cũng buộc tôi phải thay đổi tất cả các hookState và useEffect khác của tôi thành React.useSateReact.useEffect

Lỗi tiếp theo sẽ trở thành: TypeError: (0 , _react.useState) is not a functiontrong một tệp khác nơi tôi sử dụng móc React.

Tôi muốn giải quyết vấn đề không thực hiện một cách giải quyết.

Tôi sử dụng microbundleđể gói thư viện của mình bằng React. Tôi sử dụng parcel-bundlerđể nhập thành phần React và kết xuất nó trong môi trường dev (trực tiếp từ src) hoặc prod (thư viện đi kèm)

Phiên bản đi kèm mà tôi sử dụng được gói cùng với .mjs

Tôi cũng đã kiểm tra đầu ra của gói .mjs rút gọn và bên trong React được nhập như thế này:

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

Có vẻ tốt với tôi.

Điều tôi thực sự không hiểu là làm thế nào việc nhập khẩu được cơ cấu lại sẽ phá vỡ nó, nhưng chỉ cần thực hiện React.useEffect sẽ hoạt động tốt?

Đây là gói.json của tôi

{
  "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": "**"
  }
}

Cũng đáng chú ý, chỉ có React tôi gặp vấn đề này. Tất cả hàng nhập khẩu tái cấu trúc khác của tôi chỉ hoạt động tốt.


Sử dụng nhập khẩu có tên không giống như tham chiếu các thành viên của xuất mặc định. Tôi đoán là, tại thời điểm phát triển, bạn có một số trình tải bổ sung đang thực hiện một số shenanigans để giải quyết các vấn đề tương thích di sản giữa các trình tải mô-đun
Aluan Haddad

1
bạn có thể thử globalcờ --globals react=Reactvà thêm React làm phụ thuộc ngang hàng <- Mặc dù nó có thể không phải là một sửa chữa thích hợp. Nhìn vào vấn đề này: github.com/developit/microbundle/issues/537 có vẻ như đến từyarn
Jee Mok

1
Bạn cũng có thể thử cài đặt microbundle @ next để xem cái đó có hoạt động không? chỉ để kiểm tra xem đó có thực sự là vấn đề của phiên bản microbundle hiện tại không
Jee Mok

Nếu bạn đang sử dụng TypeScript, bạn cũng có thể muốn xem xét vấn đề này: github.com/developit/microbundle/issues/564
Jee Mok

1
Tôi đoán là nó đã xảy ra vì sử dụng microbundlerthay vì react-scriptscho xây dựng sản xuất, hoặc một cái gì đó thay đổi cấu hình bộ đóng gói theo cách xấu. Tôi muốn thu hút sự chú ý của bạn, các tên hook nên bắt đầu bằng usevà có thể trong dòng import ue,{useEffect as pe,useState as fe}from"react";này sử dụngEffect được nhập khi có pelỗi xảy ra với phản ứng. Vì vậy, bạn đã thử xây dựng với create-react-appreact-scripts?
Makan

Câu trả lời:


4

Có vẻ như microbundlerkhông chịu được React. Điều này tạo ra một gói cố gắng sử dụng reacttừ phạm vi toàn cầu, thay vào Reactđó thực sự phơi bày.

Vì lý do tương tự, cách giải quyết của bạn với React.useEffectcác tác phẩm như mong đợi, chỉ cần tưởng tượng rằng nó trông như thế nào window.React.useEffect.

Đây là một ví dụ về một ứng dụng nguyên thủy:

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'));

Sau khi bó với microbundlenó chỉ bị hỏng hoàn toàn, nhưng khi bạn cố gắng bó với

microbundle --globals react=React

như đề xuất chính xác @Jee Mok, nó sẽ tạo ra gói chính xác. Tôi hy vọng ý kiến ​​sẽ giải thích những gì đã xảy ra.

!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>

Và, nhân tiện, "nhập khẩu tái cấu trúc" hoàn toàn không đáng trách.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.