React 在第一次渲染时为空

问题描述 投票:0回答:1

我正在使用我们的自定义库,它与 Vite 捆绑在一起,但不包括 React,我检查了一下,发现我只有一个 React 实例,并且定义了 React。但在第一次渲染时,使用 vite-plugin-ssr (VPS) 时,我看到以下错误。我还尝试在项目内重新定义钩子,然后我就不再看到错误了。

react-dom.development.js:20662 Uncaught Error: Cannot read properties of null (reading 'useState')
    at updateDehydratedSuspenseComponent (react-dom.development.js:20662:17)
    at updateSuspenseComponent (react-dom.development.js:20362:16)
    at beginWork (react-dom.development.js:21624:14)
    at beginWork$1 (react-dom.development.js:27426:14)
    at performUnitOfWork (react-dom.development.js:26557:12)
    at workLoopSync (react-dom.development.js:26466:5)
    at renderRootSync (react-dom.development.js:26434:7)
    at performConcurrentWorkOnRoot (react-dom.development.js:25738:74)
    at workLoop (scheduler.development.js:266:34)
    at flushWork (scheduler.development.js:239:14)

我知道这可能会发生,如果:

  1. React 版本不匹配 => 我检查了项目组件库和前端项目使用 18.2.0
  2. react 和 react-dom 未列为对等依赖项 => 还检查了它是否在组件库中列出
  3. 单例钩子问题,我检查了是否有多个反应实例。在前端项目中,我将一些内容附加到 React 对象,然后附加到组件库中的 console.log,我可以看到附加的字符串
// in project
React.test = 'test'
...
// in component lib
console.log(React.test) // logs test

我的捆绑组件库的配置: vite.config.ts

/// <reference types="vitest" />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import dts from 'vite-plugin-dts';

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/index.ts'),
      formats: ['es', 'cjs'],
      name: '@workdigtital/component-library-react',
      fileName: (format) => `index.${format}.js`
    },
    rollupOptions: {
      external: ['react', 'react-dom'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM'
        },
        exports: 'named'
      }
    }
  },
  plugins: [react(), dts({ insertTypesEntry: true })],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/tests/setup.ts'],
    exclude: ['**/node_modules/**', '**/dist/**', '**/coverage/**', '**.stories**', '.storybook/**', '**.types**'],
    coverage: {
      all: true,
      exclude: ['**/*.stories.tsx', '.storybook/**'],
      provider: 'c8',
      reporter: ['cobertura', 'html']
    }
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@flaticon': path.resolve(__dirname, './node_modules/@flaticon')
    }
  }
});

我想我可能捆绑了一些错误的东西,以便它可以被 VPS 正确使用?在我们不使用 VPS 的项目中我没有看到这个问题。谁能指出我还可以调查什么的方向?

附录

组件库中的钩子:

function useWindowSize(): TWindowSize {
  console.log('useWindowSize');
  console.log('useWindowSize: React', React);
  console.log('useWindowSize: useState', useState);
  console.log('useWindowSize: useState', useEffect);
  const [windowSize, setWindowSize] = useState<TWindowSize>({
    width: 1600,
    height: 1200
  });
  useEffect(() => {
    function handleResize() {
      console.log('handleResize', React);
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    }
    window.addEventListener('resize', handleResize);
    handleResize();
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return windowSize;
}

export default useWindowSize;

我的项目的Vite配置:

/// <reference types="vitest" />
import react from '@vitejs/plugin-react';
import autoprefixer from 'autoprefixer';
import { defineConfig } from 'vite';
import circleDependency from 'vite-plugin-circular-dependency';
import ssr from 'vite-plugin-ssr/plugin';
import path from 'path';

console.log(process.env.IS_STORYBOOK ? 'Vite uses plugin set for storybook' : 'Vite uses plugin set for app');

const plugins = process.env.IS_STORYBOOK
  ? [(react(), circleDependency({}))]
  : [
      (react(), circleDependency({})),
      ssr({
        prerender: true
      })
    ];

// https://vitejs.dev/config/
export default defineConfig({
  plugins,
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/tests/setup.ts'],
    exclude: ['**/node_modules/**', '**/dist/**', '**/coverage/**', '**.stories**', '**.types**'],
    coverage: {
      all: true,
      provider: 'c8',
      reporter: ['cobertura', 'html']
    }
  },
  css: {
    postcss: {
      plugins: [autoprefixer()]
    }
  },
  resolve: {
    alias: {
      '#': path.resolve(__dirname, './src'),
      '#components': path.resolve(__dirname, './src/UI/components'),
      '#layouts': path.resolve(__dirname, './src/UI/layouts'),
      '#pages': path.resolve(__dirname, './src/pages'),
      '#providers': path.resolve(__dirname, './src/providers'),
      '#widgets': path.resolve(__dirname, './src/UI/widgets')
    }
  },
  ssr: {
    noExternal: ['primereact']
  },
  build: {
    sourcemap: 'inline'
  }
});

我使用的工具:

  • 反应
  • Vite-插件-ssr
reactjs vite rollupjs vite-plugin-ssr
1个回答
0
投票

我能够通过删除解决问题 从“vite-plugin-circular-dependency”导入circleDependency 在 vite 配置中。

© www.soinside.com 2019 - 2024. All rights reserved.