// pages/index.js
// 引入 React 库
import React from'react';
// 定义一个函数组件,这就是我们要渲染的页面
const HomePage = () => {
return (
// 返回一个包含标题和段落的 JSX 元素
欢迎来到我的网站
这是一个使用 Next.js 进行服务端渲染的页面
);
};
// 导出这个组件,Next.js 会自动处理它的渲染
export default HomePage;
// 安装 mobx 和 mobx-react 库
// npm install mobx mobx-react
// stores/counterStore.js
// 引入 mobx 中的 observable 和 action
import { makeObservable, observable, action } from'mobx';
// 定义一个计数器的状态管理类
class CounterStore {
// 定义一个可观察的状态,初始值为 0
count = 0;
constructor() {
// 让这个类的属性和方法具有 mobx 的特性
makeObservable(this, {
count: observable,
increment: action,
decrement: action
});
}
// 定义一个增加计数的动作
increment = () => {
this.count++;
};
// 定义一个减少计数的动作
decrement = () => {
this.count--;
};
}
// 创建一个计数器状态管理的实例
const counterStore = new CounterStore();
// 导出这个实例,方便其他组件使用
export default counterStore;
// components/Counter.js
// 引入 React 和 mobx-react 中的 observer
import React from'react';
import { observer } from'mobx-react';
// 引入上面定义的计数器状态管理实例
import counterStore from '../stores/counterStore';
// 使用 observer 包裹组件,让组件能响应状态的变化
const Counter = observer(() => {
return (
当前计数: {counterStore.count}
);
});
// 导出这个组件
export default Counter;
// hooks/useLocalStorage.js
// 引入 React 的 useState 和 useEffect
import React, { useState, useEffect } from'react';
// 定义一个自定义 Hook,用于在本地存储中管理数据
const useLocalStorage = (key, initialValue) => {
// 使用 useState 来管理数据,初始值从本地存储中获取,如果没有则使用传入的初始值
const [value, setValue] = useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue? JSON.parse(storedValue) : initialValue;
});
// 使用 useEffect 来监听 value 的变化,当 value 变化时更新本地存储
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
// 返回一个数组,包含数据和修改数据的函数
return [value, setValue];
};
// 导出这个自定义 Hook
export default useLocalStorage;
// components/StorageExample.js
// 引入 React 和上面定义的自定义 Hook
import React from'react';
import useLocalStorage from '../hooks/useLocalStorage';
// 定义一个使用自定义 Hook 的组件
const StorageExample = () => {
// 使用自定义 Hook 来管理本地存储中的数据,初始值为 '默认值'
const [storedValue, setStoredValue] = useLocalStorage('myData', '默认值');
return (
本地存储的值: {storedValue}
setStoredValue(e.target.value)}
/>
);
};
// 导出这个组件
export default StorageExample;
React.memo
来避免不必要的组件渲染。// components/MyComponent.js
// 引入 React
import React from'react';
// 定义一个普通的函数组件
const MyComponent = ({ name }) => {
console.log('组件渲染了');
return 你好,{name}
;
};
// 使用 React.memo 包裹组件,只有当 name 属性变化时才重新渲染
const MemoizedComponent = React.memo(MyComponent);
// 导出这个经过优化的组件
export default MemoizedComponent;
// App.js
// 引入 React 和上面优化后的组件
import React, { useState } from'react';
import MemoizedComponent from './components/MyComponent';
// 定义一个父组件
const App = () => {
// 使用 useState 来管理一个布尔值状态
const [toggle, setToggle] = useState(false);
// 定义一个固定的名字
const name = '张三';
return (
{/* 使用优化后的组件 */}
);
};
// 导出这个父组件
export default App;
// components/IoTDeviceControl.js
// 引入 React 和 useState
import React, { useState, useEffect } from'react';
// 定义一个和物联网设备交互的组件
const IoTDeviceControl = () => {
// 使用 useState 来管理设备的状态,初始状态为关闭
const [deviceStatus, setDeviceStatus] = useState('关闭');
// 模拟和物联网设备通信的函数
const toggleDevice = async () => {
// 这里应该是实际的网络请求,和设备的 API 交互
// 为了简单,我们用 setTimeout 模拟请求
await new Promise((resolve) => setTimeout(resolve, 1000));
setDeviceStatus(deviceStatus === '打开'? '关闭' : '打开');
};
return (
设备状态: {deviceStatus}
);
};
// 导出这个组件
export default IoTDeviceControl;
通过学习这些内容,你就能在 React 的世界里更上一层楼,做出更厉害、更实用的应用啦!
react-three-fiber
库,它能让咱们在 React 里轻松用 WebGL 创建 3D 场景。// 引入 React 库
import React from'react';
// 引入 react-three-fiber 里的 Canvas 组件,用来创建 3D 画布
import { Canvas } from '@react-three/fiber';
// 引入 mesh 和 boxGeometry 等,用来创建 3D 物体
import { Mesh, BoxGeometry, MeshBasicMaterial } from 'three';
// 定义一个 3D 场景组件
const Scene = () => {
return (
);
};
// 导出这个组件,方便其他地方使用
export default Scene;
tensorflow.js
库在 React 里运行简单的机器学习模型。// 引入 React 和 useState 钩子
import React, { useState, useEffect } from'react';
// 引入 tensorflow.js 库
import * as tf from '@tensorflow/tfjs';
// 定义一个使用机器学习的组件
const MLComponent = () => {
// 用 useState 来管理预测结果,初始为空
const [prediction, setPrediction] = useState('');
useEffect(() => {
const runModel = async () => {
// 加载一个简单的线性回归模型
const model = tf.sequential();
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
model.compile({ optimizer: 'sgd', loss: 'meanSquaredError' });
// 准备训练数据
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([2, 4, 6, 8], [4, 1]);
// 训练模型
await model.fit(xs, ys, { epochs: 10 });
// 进行预测
const input = tf.tensor2d([5], [1, 1]);
const output = model.predict(input);
const outputValue = await output.data();
setPrediction(outputValue[0].toString());
};
runModel();
}, []);
return (
预测结果: {prediction}
);
};
// 导出这个组件
export default MLComponent;
// components/Button.js
// 引入 React
import React from'react';
// 定义一个简单的按钮组件
const Button = ({ text, onClick }) => {
return (
);
};
// 导出这个按钮组件
export default Button;
// __tests__/Button.test.js
// 引入 React Testing Library 里的 render 和 screen
import { render, screen } from '@testing-library/react';
// 引入要测试的按钮组件
import Button from '../components/Button';
// 写一个测试用例,看看按钮能不能正常显示文字
test('按钮能显示文字', () => {
// 渲染按钮组件
render(
single-spa
实现简单的微前端架构。// 主应用(root-config.js)
// 引入 single-spa 库
import { registerApplication, start } from'single-spa';
// 注册一个微前端应用
registerApplication({
// 应用的名字
name: '@my-org/micro-frontend',
// 加载应用的函数
app: () => System.import('@my-org/micro-frontend'),
// 决定什么时候加载应用的函数
activeWhen: ['/micro-frontend']
});
// 启动 single-spa
start();
// 微前端应用(src/index.js)
// 引入 single-spa-react 里的 singleSpaReact
import singleSpaReact from'single-spa-react';
// 引入 React 和要渲染的根组件
import React from'react';
import ReactDOM from'react-dom/client';
import Root from './Root';
// 创建一个生命周期函数
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: Root,
// 可选的,设置加载中显示的内容
loadingComponent: () => 加载中...
});
// 导出生命周期函数,供主应用使用
export const { bootstrap, mount, unmount } = lifecycles;
react-i18next
库实现国际化。// i18n.js
// 引入 i18n 库和一些插件
import i18n from 'i18next';
import { initReactI18next } from'react-i18next';
// 引入不同语言的翻译文件
import translationEN from './locales/en/translation.json';
import translationZH from './locales/zh/translation.json';
// 配置 i18n
i18n
.use(initReactI18next)
.init({
// 默认语言
lng: 'en',
// 回退语言
fallbackLng: 'en',
// 资源,包含不同语言的翻译内容
resources: {
en: {
translation: translationEN
},
zh: {
translation: translationZH
}
},
interpolation: {
escapeValue: false
}
});
// 导出配置好的 i18n
export default i18n;
// App.js
// 引入 React 和 useTranslation 钩子
import React from'react';
import { useTranslation } from'react-i18next';
// 引入配置好的 i18n
import './i18n';
// 定义一个使用国际化的组件
const App = () => {
// 使用 useTranslation 钩子获取 t 函数,用于翻译文字
const { t } = useTranslation();
return (
{/* 使用 t 函数翻译文字 */}
{t('欢迎来到我的网站')}
);
};
// 导出这个组件
export default App;
通过学习这些内容,你就能在 React 的道路上越走越远,做出功能超强大、体验超棒的网页应用啦!
除了react-three-fiber库,还有哪些库可以用于React和WebGL的结合?
react - three - drei
是基于 react - three - fiber
的一个辅助库,就像是给 react - three - fiber
这个工具盒里又添了好多实用的小工具。它提供了大量预构建的组件和钩子,能让我们更轻松地创建复杂的 3D 场景,不用每次都从头开始写代码。// 引入 React 库
import React from'react';
// 引入 react - three - fiber 里的 Canvas 组件,用于创建 3D 画布
import { Canvas } from '@react - three/fiber';
// 引入 react - three - drei 里的 OrbitControls 和 Stats 组件
import { OrbitControls, Stats } from '@react - three/drei';
// 定义一个 3D 场景组件
const Scene = () => {
return (
);
};
// 导出这个组件,方便其他地方使用
export default Scene;
react - webgl - three
也是一个能把 React 和 WebGL 结合起来的库。它的特点是简化了在 React 应用里使用 Three.js(一个流行的 WebGL 库)的过程,让我们可以更方便地在 React 组件里创建和管理 3D 场景。// 引入 React 库
import React from'react';
// 引入 react - webgl - three 里的 WebGLRenderer 组件
import { WebGLRenderer } from'react - webgl - three';
// 引入 Three.js 里的一些对象
import * as THREE from 'three';
// 定义一个 3D 场景组件
const WebGLScene = () => {
// 创建一个场景对象
const scene = new THREE.Scene();
// 创建一个相机对象
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建一个渲染器对象
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// 创建一个立方体的几何形状
const geometry = new THREE.BoxGeometry();
// 创建一个材质对象
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 创建一个立方体网格对象
const cube = new THREE.Mesh(geometry, material);
// 将立方体添加到场景中
scene.add(cube);
// 设置相机的位置
camera.position.z = 5;
// 定义一个渲染函数
const render = () => {
requestAnimationFrame(render);
// 让立方体旋转
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
// 调用渲染函数
render();
return (
{/* 使用 WebGLRenderer 组件渲染场景 */}
);
};
// 导出这个组件
export default WebGLScene;
// 引入 React 库
import React from'react';
// 引入 react - three - fiber 里的 Canvas 组件
import { Canvas } from '@react - three/fiber';
// 引入 react - three - postprocessing 里的一些组件
import { EffectComposer, DepthOfField } from '@react - three/postprocessing';
// 定义一个 3D 场景组件
const PostProcessingScene = () => {
return (
);
};
// 导出这个组件
export default PostProcessingScene;
这些库都能帮助我们在 React 项目里更方便地使用 WebGL 来创建 3D 场景,每个库都有自己的特点和优势,你可以根据项目的具体需求来选择使用。
React与WebGL结合的性能优化方法有哪些?
// 引入 React 和 react - three - fiber 的相关组件
import React from'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Mesh, BoxGeometry, MeshBasicMaterial } from 'three';
// 创建一个简单的 3D 场景组件
const OptimizedScene = () => {
// 创建一个立方体的引用
const cubeRef = React.useRef();
// 使用 useFrame 钩子在每一帧更新立方体的旋转
useFrame(() => {
if (cubeRef.current) {
cubeRef.current.rotation.x += 0.01;
cubeRef.current.rotation.y += 0.01;
}
});
return (
);
};
export default OptimizedScene;
在这个例子中,我们只创建了一个简单的立方体,没有添加过多复杂的物体,减少了场景的复杂度,从而提高性能。
import React from'react';
import { Canvas } from '@react-three/fiber';
import { Mesh, SphereGeometry, MeshBasicMaterial, TextureLoader } from 'three';
const TextureOptimizedScene = () => {
// 创建一个纹理加载器
const textureLoader = new TextureLoader();
// 加载纹理图片,这里可以选择合适分辨率的图片
const texture = textureLoader.load('low - res - texture.jpg');
return (
);
};
export default TextureOptimizedScene;
这里我们使用 TextureLoader
加载纹理,并且选择了低分辨率的图片,减少了纹理的内存占用,提高性能。
import React from'react';
import { Canvas } from '@react-three/fiber';
import { BufferGeometry, BufferAttribute, Mesh, MeshBasicMaterial } from 'three';
const BatchScene = () => {
// 创建一个自定义的几何体
const geometry = new BufferGeometry();
// 定义顶点数据
const positions = new Float32Array([
0, 0, 0,
1, 0, 0,
0, 1, 0
]);
// 设置顶点属性
geometry.setAttribute('position', new BufferAttribute(positions, 3));
return (
);
};
export default BatchScene;
在这个例子中,我们创建了一个自定义的几何体,然后让多个网格使用这个几何体,实现了批处理,减少了绘制调用的次数。
import React from'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Mesh, BoxGeometry, MeshBasicMaterial, PerspectiveCamera } from 'three';
const CullingScene = () => {
// 创建一个相机的引用
const cameraRef = React.useRef();
useFrame(() => {
if (cameraRef.current) {
// 可以在这里更新相机的位置和角度
cameraRef.current.position.x += 0.01;
}
});
return (
);
};
export default CullingScene;
在这个例子中,我们创建了一个相机,并且可以通过更新相机的位置和角度,让程序只绘制相机能看到的物体,实现视锥体剔除。
import React from'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Mesh, SphereGeometry, MeshBasicMaterial } from 'three';
const AnimationOptimizedScene = () => {
// 创建一个球体的引用
const sphereRef = React.useRef();
useFrame(() => {
if (sphereRef.current) {
// 简单的旋转动画,减少计算量
sphereRef.current.rotation.x += 0.005;
}
});
return (
);
};
export default AnimationOptimizedScene;
这里我们只给球体添加了一个简单的旋转动画,减少了动画的复杂度,提高了性能。
React与WebGL结合的实战项目
平常咱们做的网页大多是二维平面的,画面比较单调。WebGL 就像是给网页开了个“3D 特效外挂”,能让网页呈现出炫酷的三维效果。咱们要把 React 和 WebGL 结合起来,做一个简单的 3D 立方体旋转展示的网页,让用户能直观看到 3D 物体的动态效果。
要做这个项目,得先安装一些必要的库。主要用到 react-three-fiber
,它是一个基于 React 的 WebGL 渲染库,能让我们在 React 里轻松创建 3D 场景;还有 three.js
,它是 WebGL 的底层库,提供了很多 3D 相关的功能。可以用下面的命令来安装:
npm install @react-three/fiber three
// 引入 React 库,因为我们要用 React 来构建组件
import React, { useRef, useEffect } from'react';
// 引入 react-three-fiber 里的 Canvas 组件,这个组件就像是一个 3D 画布,我们可以在上面绘制 3D 物体
import { Canvas } from '@react-three/fiber';
// 引入 three.js 里的 OrbitControls 控件,它能让我们用鼠标控制 3D 场景的视角,比如旋转、缩放等
import { OrbitControls } from '@react-three/drei';
// 定义一个 3D 场景组件
const Scene = () => {
// 使用 useRef 钩子创建一个引用,用来获取立方体对象,方便后续操作
const cubeRef = useRef();
// 使用 useEffect 钩子,它会在组件渲染完成后执行,就像一个小助手,帮我们做一些初始化和后续操作
useEffect(() => {
// 定义一个动画函数,这个函数会在每一帧被调用,实现立方体的旋转效果
const animate = () => {
// 通过 requestAnimationFrame 函数不断调用自身,形成一个循环,实现动画效果
requestAnimationFrame(animate);
// 让立方体在 x 轴上每秒旋转 0.01 弧度
cubeRef.current.rotation.x += 0.01;
// 让立方体在 y 轴上每秒旋转 0.01 弧度
cubeRef.current.rotation.y += 0.01;
};
// 调用动画函数,开始动画
animate();
}, []);
return (
// 使用 Canvas 组件创建 3D 画布
);
};
// 定义一个 App 组件,它是整个应用的根组件
const App = () => {
return (
{/* 在 App 组件里使用我们定义的 3D 场景组件 */}
);
};
// 导出 App 组件,这样其他文件就可以使用它了
export default App;
React
、Canvas
和 OrbitControls
,这些是构建 3D 场景的基础。Scene
组件:
useRef
用来获取立方体对象,方便后续对立方体进行操作。useEffect
里定义了 animate
函数,通过 requestAnimationFrame
不断调用自身,实现立方体的旋转效果。return
里,使用
创建 3D 画布,添加了环境光和点光源让场景有亮度和立体感,创建了一个蓝色的立方体,还添加了 OrbitControls
让用户可以用鼠标控制视角。App
组件:在 App
组件里使用 Scene
组件,把 3D 场景展示出来。把上面的代码保存为 App.js
,然后在项目的入口文件(一般是 index.js
)里引入并渲染 App
组件:
// 引入 React 库
import React from'react';
// 引入 ReactDOM 库,用于将 React 组件渲染到 DOM 中
import ReactDOM from'react-dom/client';
// 引入我们定义的 App 组件
import App from './App';
// 创建一个根节点,用于挂载 React 应用
const root = ReactDOM.createRoot(document.getElementById('root'));
// 将 App 组件渲染到根节点上
root.render( );
然后在终端里运行项目:
npm start
这样就能在浏览器里看到一个旋转的蓝色立方体啦,你还可以用鼠标拖动来改变视角,是不是很酷炫!