【问题标题】:React hooks widget works when used directly but not when imported from NPMReact hooks 小部件在直接使用时有效,但在从 NPM 导入时无效
【发布时间】:2020-07-24 15:52:59
【问题描述】:

我有一个相对简单的 React Hooks 小部件示例,它的功能是提供上下文挂钩以提供可以设置一些字符串并切换当前 Material UI 主题的状态。这是工作的demo。通过单击标有“下一个主题”的按钮,您可以看到页面在黄色和蓝色之间切换,以及一些指示主题名称的文本更改。

这是一个人为的例子,但我的想法是在我的网站顶部,我使用上下文提供程序包装所有内容,以便任何嵌套的小部件都可以访问共享状态。看起来像这样:

import React from "react";

import { AppContext } from "./AppContext";
import { ThemeContextProvider } from "./ThemeContext";

export default function App(props) {
  return (
    <div>
      <ThemeContextProvider>
        <AppContext>{props.children}</AppContext>
      </ThemeContextProvider>
    </div>
  );
}

正如我在上面链接的演示中所说的那样,一切正常。但是当我将此代码发布到 NPM 然后在另一个项目中使用它时,除了一个导入部分之外,它大部分都可以工作——主题颜色不会改变。所有其他状态更改都正常工作 - 所有其他状态更改都是文本的,没有问题,但颜色不会改变。

主题由 Material UI 提供,我怀疑我将所有这些代码汇总以发布到 NPM 的方式存在问题。我正在使用 Rollup——这里是 rollup.config.js:

import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import external from 'rollup-plugin-peer-deps-external';
import resolve from 'rollup-plugin-node-resolve';
import json from '@rollup/plugin-json';
const {terser} = require('rollup-plugin-terser');

import pkg from './package.json';

export default {
  input: 'src/index.js',
  output: [
    {
      file: pkg.main,
      format: 'cjs',
      sourcemap: true
    },
    {
      file: pkg.module,
      format: 'es',
      sourcemap: true
    }
  ],
  plugins: [
    external(),
    // url({ exclude: ['**/*.svg'] }),
    babel({
      exclude: 'node_modules/**',
      runtimeHelpers: true
    }),
    resolve({
      preferBuiltins: true,
      browser: true
    }),
    commonjs({
      include: 'node_modules/**',
      browser: true,
      namedExports: {
        'node_modules/react/index.js': [
          'createContext',
          'useContext',
          'useEffect',
          'useState'
        ],
        'node_modules/react-is/index.js': [
          'ForwardRef',
          'Memo'
        ],
        'node_modules/prop-types/index.js': [
          'elementType'
        ]
      }
    }),
    terser(),
    json()
  ]
};

这是我的 package.json:

{
  "name": "@data-factory/theme-context-test",
  "version": "0.0.1",
  "description": "Code from CodeSandbox",
  "author": "sellis42",
  "main": "dist/index.js",
  "module": "dist/index.es.js",
  "jsnext:main": "dist/index.es.js",
  "engines": {
    "node": ">=8",
    "npm": ">=5"
  },
  "publishConfig": {
    "access": "public"
  },
  "scripts": {
    "build": "rollup -c",
    "start": "rollup -c -w",
    "prepare": "npm run build",
    "predeploy": "cd example && npm install && npm run build"
  },
  "peerDependencies": {
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@babel/plugin-transform-runtime": "^7.9.0",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.0.0",
    "@babel/runtime": "^7.9.2",
    "@material-ui/core": "^4.9.8",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/styles": "^4.9.6",
    "@rollup/plugin-json": "^4.0.2",
    "cross-env": "^5.2.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-scripts": "^3.4.0",
    "rollup": "^1.32.1",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-commonjs": "^9.3.4",
    "rollup-plugin-node-resolve": "^4.2.4",
    "rollup-plugin-peer-deps-external": "^2.2.2",
    "rollup-plugin-terser": "^4.0.4",
    "typeface-roboto": "0.0.75"
  }
}

我感觉好像我的汇总配置中缺少一些东西。该项目在我的本地开发系统上,与链接代码略有不同。我基本上拥有我在小部件模块的根目录中发布的所有代码,以及一个演示如何使用小部件的示例文件夹。我使用 npm 链接,以便示例小部件可以使用它,这就是我看到我要解决的问题的地方。我可以将整个根小部件复制到示例 src 的子文件夹中,然后从那里而不是从 NPM 中导入它,它会再次工作。

任何帮助或想法将不胜感激。如果有人有兴趣深入了解,我可以将我所有的代码放到 Git 中。

【问题讨论】:

    标签: npm material-ui react-hooks


    【解决方案1】:

    我通过不在 ThemeContext 中使用 ThemeProvider 完全回避了这个问题。以下是 ThemeContext 钩子返回的内容(源代码缩写):

    return (
        <ThemeContext.Provider value={{theme, setTheme ... }}>
          <ThemeProvider theme={theme}>{props.children}</ThemeProvider>
        </ThemeContext.Provider>
      );
    

    我把它改成了:

    return (
        <ThemeContext.Provider value={{theme, setTheme ... }}>
          {props.children}
        </ThemeContext.Provider>
      );
    

    然后,提供 ThemeProvider 是孩子们的责任。只要我避免在我的钩子中提供 ThemeProvider 我似乎没问题。

    我不知道为什么会这样,但我可以忍受。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多