【问题标题】:Load Component Only once in React js在 React js 中只加载一次组件
【发布时间】:2021-03-20 06:19:44
【问题描述】:

所以我有一个 React 应用程序 它有 2 页 可以说第一个是家庭,第二个是我的投资组合部分 我的投资组合部分有 2 个功能组件

Home.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 一切正常,但当我再次访问它们时,它们每次都会重新加载

我不希望 Portfolio 部分中的 Projects 组件加载多次 我希望它只在启动时/启动网站时加载一次,甚至在访问投资组合部分(即在后台)之前,因为它有大文件需要时间来加载并保持不变,直到用户自愿刷新页面。

组件中有一些使用three.js的3d模型 所以它不是一个静态网站 会有自己的动画 但是每次访问页面时加载整个组件会花费很多时间

推荐组件会动态变化

所以在 2 个组件中,我希望一个组件保持不变而无需重新加载 其他动态变化

如何让组件只加载一次 任何建议都会帮助我 我看到了 UseMemo 但我不知道这是否对我有帮助 如果是这样,有人可以解释如何在我的情况下使用它

【问题讨论】:

    标签: javascript reactjs three.js react-router react-hooks


    【解决方案1】:

    当相关组件(Projects)首次渲染时,创建动画,并将其缓存在组件外部的变量中(示例中为let animation)。每当安装组件时,从外部变量中获取动画,然后启动它。当它被卸载时停止动画。

    注意:如果您只渲染组件的单个实例,这将起作用。如果你要渲染多个实例,你需要想出一个系统来缓存每个实例的重新渲染动画——可能是某种地图,每个实例都有一个常量 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>

    【讨论】:

    • 您好,感谢您的帮助,这里您只是在 2 个组件之间切换,当我们路由到单独的页面时可以使用它。就像我在主页中单击一个学生姓名一样,它将路由到该学生组合,在那里它将具有相同的静态 3d 模型项目和不同的推荐,在路由每次刷新页面时如何做到这一点。
    • 3d 模型不是保存在页面上,而是作为变量保存。您可以在文件中创建一个单例,并将模型保存到其中,然后将其导入到两个组件中。页面(和路由)是组件,因此是否使用路由无关紧要。试试看。
    猜你喜欢
    • 2020-01-06
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    相关资源
    最近更新 更多