javascript - 在 React js 中只加载一次组件
问题描述
所以我有一个 React 应用程序它有 2 个页面让我们说第一个是主页,第二个是我的投资组合部分,我的投资组合部分有 2 个功能组件
主页.js
import React from 'react'
const Home = () => {
return (
<h1>Home Screen</h1>
)
}
export default Home
投资组合部分
import React from 'react'
import Projects from '../components/Projects'
import Testimonials from '../components/Testimonials'
const Portfolio = () => {
return (
<>
<h1>Portfolio</h1>
<Projects/>
<Testimonials/>
</>
)
}
export default Portfolio
当我访问 Home 时,Portfolio 一切正常,但是当我再次访问它们时,它们每次都重新加载
我不希望投资组合部分中的项目组件加载不止一次我希望它在启动时/启动站点时仅加载一次,甚至在访问投资组合部分(即在后台)之前,因为它有大文件将需要时间来加载并保持不变,直到用户自愿刷新页面。
该组件中有一些使用three.js的3d模型所以它不是一个静态站点它将有自己的动画但是每次访问页面时加载整个组件会花费很多时间
但是推荐组件会动态变化
因此,在 2 个组件中,我希望一个保持不变而无需重新加载,而另一个则动态更改
我怎样才能只加载一次组件任何建议都会帮助我我看到了 UseMemo 但我不知道这是否会对我有帮助
解决方案
首次渲染相关组件 ( Projects
) 时,创建动画并将其缓存在组件外部的变量中(let animation
在示例中)。每当安装组件时,从外部变量中获取动画,然后启动它。当它被卸载时停止动画。
注意:如果您只渲染组件的单个实例,这将起作用。如果你要渲染多个实例,你需要想出一个系统来缓存每个实例的重新渲染动画 - 可能是某种 Map ,每个实例都有一个常量 id。
示例- 切换页面,动画将继续
const { Fragment, useState, useEffect, useRef } = React
let animation
const Projects = () => {
const container = useRef();
useEffect(() => {
if(!animation) {
animation = createAnimation()
}
container.current.appendChild(animation.domElement)
animation.start()
return () => animation.stop()
}, [])
return (
<div ref={container} />
)
}
const Home = () => (
<span>Home Screen</span>
)
const Portfolio = () => (
<Fragment>
<span>Portfolio</span>
<Projects />
</Fragment>
)
const App = () => {
const [showPortfolio, setShowPortfolio] = useState(false)
return (
<div>
<button
onClick={() => setShowPortfolio(!showPortfolio)}>
Toggle
</button>
{showPortfolio ? <Portfolio /> : <Home />}
</div>
)
}
ReactDOM.render(
<App />,
root
)
function createAnimation() {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth / 2, window.innerHeight / 2);
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;
let requestId;
const animate = () => {
requestId = requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
return {
start: animate,
stop: () => cancelAnimationFrame(requestId),
domElement: renderer.domElement
}
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js" integrity="sha512-n8IpKWzDnBOcBhRlHirMZOUvEq2bLRMuJGjuVqbzUJwtTsgwOgK5aS0c1JA647XWYfqvXve8k3PtZdzpipFjgg==" crossorigin="anonymous"></script>
<div id="root"></div>
推荐阅读
- python - 在 Pandas 中连续对每个链接发出 HTTP 请求
- typescript - 通过 npm 与使用本机包(通过 apt)为 Ubuntu 安装 typescript
- json - 无法正确获取 JSON 数据
- kotlin - 如何从gcp中的spring cloud函数发回自定义http响应代码?
- c# - Asp.Net Core 3.1 多个依赖的自定义配置提供程序
- react-native - 我没有使用 React Native SafeAreaView 但似乎我一直在使用。我怎样才能做到这一点?
- ios - 无法从 Apple HealthKit 访问 Active Energy 的汇总日值
- discord.py - “except”函数不适用于 discord.py
- c++ - boost::extension.hpp 的原因没有为无序容器和其他一些容器定义 hash_value()
- python - FileNotFoundError: [Errno 2] No such file or directory Azure Python 错误