Viv*_*ere 7 three.js typescript reactjs material-ui react-typescript
渲染 aBox会产生以下错误:
表达式生成的联合类型太复杂而无法表示。ts(2590)
正如我在这里看到的,这是因为同时安装了@mui/material和@react-three/drei& @react-three/fiber。
这个错误背后的原因是什么?我只Box从 导入组件mui。是否存在类型混淆或其他问题?解决方案/解决方法是什么?
重现步骤:
npx create-react-app my-app --template typescriptpackage.json "dependencies": {
"@azure/msal-browser": "^2.18.0",
"@azure/msal-react": "^1.1.0",
"@emotion/react": "^11.5.0",
"@emotion/styled": "^11.3.0",
"@mui/icons-material": "^5.0.4",
"@mui/lab": "^5.0.0-alpha.51",
"@mui/material": "^5.0.4",
"@mui/system": "^5.0.4",
"@react-three/drei": "^7.16.8",
"@react-three/fiber": "^7.0.17",
"axios": "^0.23.0",
"dotenv": "^10.0.0",
"localforage": "^1.10.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router": "^5.2.1",
"react-router-dom": "^5.3.0",
"react-scripts": "4.0.3",
"three": "^0.133.1",
"three-stdlib": "^2.5.4",
"web-vitals": "^1.1.2",
"zustand": "^3.5.14"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"@types/jest": "^26.0.24",
"@types/node": "^12.20.33",
"@types/react": "^17.0.30",
"@types/react-dom": "^17.0.9",
"@types/react-router-dom": "^5.3.1",
"@types/three": "^0.133.1",
"@typescript-eslint/eslint-plugin": "^4.29.3",
"@typescript-eslint/parser": "^4.29.3",
"cross-env": "^7.0.3",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-typescript": "^14.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"jest-when": "^3.4.1",
"rimraf": "^3.0.2",
"typescript": "^4.4.4"
},
Run Code Online (Sandbox Code Playgroud)
npm installTypescript v4.4.4src. 我把它命名为ThreeRenderer.tsx:import { Html, OrbitControls, PerspectiveCamera, useGLTF, useProgress } from '@react-three/drei';
import { Canvas, useFrame } from '@react-three/fiber';
import { FC, Suspense, useEffect, useRef, useState } from 'react';
import { AnimationAction, AnimationMixer } from 'three';
import { GLTF, GLTFLoader } from 'three-stdlib';
import create from 'zustand';
import { devtools } from 'zustand/middleware';
export const useGLTFModel = create<{ readonly model: () => GLTF | undefined }>(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
devtools((set) => ({
model: () => undefined
}))
);
export const useGLTFAnimationAction = create<{ readonly animationAction: () => AnimationAction[] | undefined }>(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
devtools((set) => ({
animationAction: () => undefined
}))
);
interface ModelProps {
readonly gltfPath: string;
readonly onLoad: () => void;
}
const Model: FC<ModelProps> = ({ gltfPath, onLoad }) => {
const model = useGLTF(gltfPath, undefined, undefined, (loader: GLTFLoader) => {
loader.manager.onLoad = onLoad;
});
// Refs
const rootRef = useRef();
const animationActionsRef = useRef<AnimationAction[]>();
// Mixer
const [mixer] = useState(() => new AnimationMixer(model.scene));
useFrame((_state, delta) => mixer.update(delta));
// Effects
useEffect(() => {
useGLTFModel.setState({ model: () => model });
animationActionsRef.current = model.animations.map((animation) => mixer.clipAction(animation, rootRef.current));
useGLTFAnimationAction.setState({ animationAction: () => animationActionsRef.current });
return () => {
model.animations.map((animation) => mixer.uncacheClip(animation));
};
}, [model, mixer]);
return <primitive ref={rootRef.current} object={model.scene} />;
};
const Progress = () => {
const { progress } = useProgress();
return (
<Html center>
<span style={{ color: 'white' }}>{progress}% loaded</span>
</Html>
);
};
const ThreeRenderer: FC<ModelProps> = ({ gltfPath, onLoad }): JSX.Element => {
const cameraRef = useRef();
return (
<Canvas>
<PerspectiveCamera ref={cameraRef} position={[0, 5, 5]} />
<OrbitControls camera={cameraRef.current} />
<ambientLight intensity={0.5} />
<Suspense fallback={<Progress />}>
{/* <Environment preset="city" /> */}
<Model gltfPath={gltfPath} onLoad={onLoad} />
</Suspense>
</Canvas>
);
};
export default ThreeRenderer;
Run Code Online (Sandbox Code Playgroud)
App.tsx并添加一个Box组件@mui/material。import React from 'react';
import logo from './logo.svg';
import './App.css';
import {Box} from '@mui/material';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<Box>
</Box>
</header>
</div>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
注意
请尝试在本地VSCode或您首选的编辑器中重现此错误。codesandbox例如,我没有设法重现这一点。我不知道为什么没有出现该问题。我怀疑这是因为他们使用不同的打字稿版本。
更新
我在 MUI 和 React-3 上都提出了问题:
Select TypeScript version command。帖子来源:FreePhoenix888。
原答案:这里
虽然我确信在某些情况下可能会发生此问题,但现在发生在我身上的原因是,安装了定义了类型声明的npm重复版本@chakra-ui/systemforwardRef().
当我跑步时,npm ls @chakra-ui/system我可以看到我同时拥有@chakra-ui/system@1.9.1和@chakra-ui/system@1.9.0。
这可能是因为某些依赖项(例如@chakra-ui/skeleton@1.2.4定义了 的精确版本)1.9.0,@chakra-ui/system而大多数包(例如@chakra-ui/menu@1.8.3)将非常开放的版本定义>=1.0.0为peerDependencies. 从npm v7peerDependencies开始,npm默认安装。
看起来这可能会导致 npm 安装最新版本的开放版本>=1.0.0,然后1.9.0单独安装特定版本,并且不够智能来删除重复数据。
我可以通过以下任一方式解决这个问题
\nrm package-lock.json && npm install --legacy-peer-deps。然而,这对 npm 安装的软件包有很大影响。
或者,向 中添加overrides(requires npm >=8.3) 以package.json指定要安装的特定版本。
"overrides": {\n "@chakra-ui/system": "1.9.1"\n }\nRun Code Online (Sandbox Code Playgroud)\n您可能必须package-lock.json在再次运行安装之前删除它来重新生成,以实际强制执行此新解决方案。
这只会确保对特定包进行重复数据删除,而不会像 \xc2\xb4--legacy-peer-deps` 那样更改其他不相关的包。
\n| 归档时间: |
|
| 查看次数: |
9160 次 |
| 最近记录: |