将 React Typescript 组件转换为 Javascript 会出错
Conversion React Typescript component into Javascript gives errors
我正在玩 React Fiber 和 React Drei 但我不想使用 Typescript 就像我在他们 git
中找到的例子一样
下面例子我已经转换了Stars.tsx with 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
该组件现在在 index.js 的第 28 行注释,因为我收到以下错误
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`.
我不明白这个错误的确切问题所在。
我从 typescript 转换为 javascript 的 stars.js 组件有什么问题?我该如何解决?
导入命名为Stars
,如:
import { Stars } from "./stars";
我正在玩 React Fiber 和 React Drei 但我不想使用 Typescript 就像我在他们 git
中找到的例子一样下面例子我已经转换了Stars.tsx with 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
该组件现在在 index.js 的第 28 行注释,因为我收到以下错误
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`.
我不明白这个错误的确切问题所在。
我从 typescript 转换为 javascript 的 stars.js 组件有什么问题?我该如何解决?
导入命名为Stars
,如:
import { Stars } from "./stars";