将 React Typescript 组件转换为 Javascript 会出现错误
我正在使用 React Fiber 和 React Drei 但我不想使用 Typescript 就像我在他们的 git
我已经转换了以下示例 Stars.tsx 与 typescriptlang 工具
这是输出
import React, { useState, useRef, useEffect, useMemo } from "react";
import { useFrame } from "@react-three/fiber";
import {
Points,
Vector3,
Spherical,
Color,
AdditiveBlending,
ShaderMaterial
} from "three";
class StarfieldMaterial extends ShaderMaterial {
constructor() {
super({
uniforms: { time: { value: 0.0 }, fade: { value: 1.0 } },
vertexShader: /* glsl */ `
uniform float time;
attribute float size;
varying vec3 vColor;
void main() {
vColor = color;
vec4 mvPosition = modelViewMatrix * vec4(position, 0.5);
gl_PointSize = size * (30.0 / -mvPosition.z) * (3.0 + sin(mvPosition.x + 2.0 * time + 100.0));
gl_Position = projectionMatrix * mvPosition;
}`,
fragmentShader: /* glsl */ `
uniform sampler2D pointTexture;
uniform float fade;
varying vec3 vColor;
void main() {
float opacity = 1.0;
if (fade == 1.0) {
float d = distance(gl_PointCoord, vec2(0.5, 0.5));
opacity = 1.0 / (1.0 + exp(16.0 * (d - 0.25)));
}
gl_FragColor = vec4(vColor, opacity);
#include <tonemapping_fragment>
#include <encodings_fragment>
}`
});
}
}
const genStar = (r) => {
return new Vector3().setFromSpherical(
new Spherical(
r,
Math.acos(1 - Math.random() * 2),
Math.random() * 2 * Math.PI
)
);
};
export const Stars = React.forwardRef(
(
{
radius = 10,
depth = 30,
count = 10,
saturation = 5,
factor = 4,
fade = false
},
ref
) => {
const material = useRef(StarfieldMaterial);
const [position, color, size] = useMemo(() => {
const positions = [];
const colors = [];
const sizes = Array.from(
{ length: count },
() => (5 + 5 * Math.random()) * factor
);
const color = new Color();
let r = radius + depth;
const increment = depth / count;
for (let i = 0; i < count; i++) {
r -= increment * Math.random();
positions.push(...genStar(r).toArray());
color.setHSL(i / count, saturation, 0.9);
colors.push(color.r, color.g, color.b);
}
return [
new Float32Array(positions),
new Float32Array(colors),
new Float32Array(sizes)
];
}, [count, depth, factor, radius, saturation]);
useFrame(
(state) =>
material.current &&
(material.current.uniforms.time.value = state.clock.getElapsedTime())
);
const [starfieldMaterial] = useState(() => new StarfieldMaterial());
return React.createElement(
"points",
{ ref: ref },
React.createElement(
"bufferGeometry",
{ attach: "geometry" },
React.createElement("bufferAttribute", {
attachObject: ["attributes", "position"],
args: [position, 3]
}),
React.createElement("bufferAttribute", {
attachObject: ["attributes", "color"],
args: [color, 3]
}),
React.createElement("bufferAttribute", {
attachObject: ["attributes", "size"],
args: [size, 1]
})
),
React.createElement("primitive", {
dispose: undefined,
ref: material,
object: starfieldMaterial,
attach: "material",
blending: AdditiveBlending,
"uniforms-fade-value": fade,
transparent: true,
vertexColors: true
})
);
}
);
然后我将此 Stars 组件粘贴到我的 codesandbox
该组件现在在第 28 行被注释index.js 因为我收到以下错误,
Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
我不明白此错误的问题到底出在哪里。
我从打字稿转换为 JavaScript 的 stars.js 组件有什么问题吗?我该如何修复它?
I am playing with React Fiber and React Drei but i do not want to use Typescript like in the examples i have found in their git
I have converted the following example Stars.tsx with typescriptlang tool
This is the output
import React, { useState, useRef, useEffect, useMemo } from "react";
import { useFrame } from "@react-three/fiber";
import {
Points,
Vector3,
Spherical,
Color,
AdditiveBlending,
ShaderMaterial
} from "three";
class StarfieldMaterial extends ShaderMaterial {
constructor() {
super({
uniforms: { time: { value: 0.0 }, fade: { value: 1.0 } },
vertexShader: /* glsl */ `
uniform float time;
attribute float size;
varying vec3 vColor;
void main() {
vColor = color;
vec4 mvPosition = modelViewMatrix * vec4(position, 0.5);
gl_PointSize = size * (30.0 / -mvPosition.z) * (3.0 + sin(mvPosition.x + 2.0 * time + 100.0));
gl_Position = projectionMatrix * mvPosition;
}`,
fragmentShader: /* glsl */ `
uniform sampler2D pointTexture;
uniform float fade;
varying vec3 vColor;
void main() {
float opacity = 1.0;
if (fade == 1.0) {
float d = distance(gl_PointCoord, vec2(0.5, 0.5));
opacity = 1.0 / (1.0 + exp(16.0 * (d - 0.25)));
}
gl_FragColor = vec4(vColor, opacity);
#include <tonemapping_fragment>
#include <encodings_fragment>
}`
});
}
}
const genStar = (r) => {
return new Vector3().setFromSpherical(
new Spherical(
r,
Math.acos(1 - Math.random() * 2),
Math.random() * 2 * Math.PI
)
);
};
export const Stars = React.forwardRef(
(
{
radius = 10,
depth = 30,
count = 10,
saturation = 5,
factor = 4,
fade = false
},
ref
) => {
const material = useRef(StarfieldMaterial);
const [position, color, size] = useMemo(() => {
const positions = [];
const colors = [];
const sizes = Array.from(
{ length: count },
() => (5 + 5 * Math.random()) * factor
);
const color = new Color();
let r = radius + depth;
const increment = depth / count;
for (let i = 0; i < count; i++) {
r -= increment * Math.random();
positions.push(...genStar(r).toArray());
color.setHSL(i / count, saturation, 0.9);
colors.push(color.r, color.g, color.b);
}
return [
new Float32Array(positions),
new Float32Array(colors),
new Float32Array(sizes)
];
}, [count, depth, factor, radius, saturation]);
useFrame(
(state) =>
material.current &&
(material.current.uniforms.time.value = state.clock.getElapsedTime())
);
const [starfieldMaterial] = useState(() => new StarfieldMaterial());
return React.createElement(
"points",
{ ref: ref },
React.createElement(
"bufferGeometry",
{ attach: "geometry" },
React.createElement("bufferAttribute", {
attachObject: ["attributes", "position"],
args: [position, 3]
}),
React.createElement("bufferAttribute", {
attachObject: ["attributes", "color"],
args: [color, 3]
}),
React.createElement("bufferAttribute", {
attachObject: ["attributes", "size"],
args: [size, 1]
})
),
React.createElement("primitive", {
dispose: undefined,
ref: material,
object: starfieldMaterial,
attach: "material",
blending: AdditiveBlending,
"uniforms-fade-value": fade,
transparent: true,
vertexColors: true
})
);
}
);
Then i have paste this Stars component in my codesandbox
The component is now commented at the row 28 of index.js because i get the following error
Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
I do not understand exactly where the problems is with this error.
What is wrong with stars.js component that i have converted from typescript to javascript? How can i fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
导入命名的
Stars
,例如:工作示例:https://codesandbox .io/s/elegant-lumiere-1wf3uo
Import the named
Stars
, like:Working example: https://codesandbox.io/s/elegant-lumiere-1wf3uo