使用到的hook: useContext
使用到的api: lazy – React
1.在utils文件夹下新建文件夹testContext
2.新建文件PersonContext.js,导出一个Context对象实例
import React from 'react'
export default React.createContext()
3.新建两个需要条件渲染的页面TestA.js 和 TestB.js,用来测试动态组件
4.新建用于封装动态组件文件Dcomponent.js
思路:
我希望达到的效果是同Vue一样,传入组件名,react就是渲染对应的组件
(1)组件懒加载
根据Vue的动态组件component的思想,首先引入需要动态渲染的组件
import TestA from './TestA.js'
import TestB from './TestB.js
因为动态组件其实是根据传入条件(组件名)进行对应组件的渲染,如果直接引入所有需要动态渲染的组件会造成不必要的加载,所以此处可用组件懒加载优化,react已经有lazy帮助声明一个懒加载的 React 组件(注意:使用lazy懒加载组件需要Suspense标签包裹 )
import React, {lazy, Suspense} from 'react'
(2)实现组件名和组件对应匹配
因为传入的是组件名,所以可以创建一个compMap对象,组件名即为compMap的键名,值为对应的组件,通过键名渲染对应键值
const compMap = {
TestA: lazy(() => import('./TestA')),
TestB: lazy(() => import('./TestB'))
}
(3)实现组件通信
引入PersonContext.js
在数据提供者用context.provider
import React, {lazy, Suspense} from 'react'
import PersonContext from "@/component/testContext/PersonContext";
const compMap = {
TestA: lazy(() => import('./TestA')),
TestB: lazy(() => import('./TestB'))
}
function Dcomponent(props) {
console.log(props, 'Dcomponent props')
let Comp = compMap[props.compName]
return (
<>
<Suspense>
<PersonContext.Provider>
<Comp value={{...props}}/>
</PersonContext.Provider>
</Suspense>
</>
)
}
export default Dcomponent
在数据使用者用useContext
TestA.js:
import React,{useContext} from 'react'
import PersonContext from "@/component/testContext/PersonContext";
function TestA() {
const {person} = useContext(PersonContext)
console.log(person, 'person')
return (
<>
<h1>我是TestA页面</h1>
<h2>个人信息</h2>
<h3>姓名:{person.name}</h3>
<h3>年龄:{person.age}</h3>
<h3>爱好:{person.hobby}</h3>
</>
)
}
export default TestA
(4)使用动态组件
NavBar.js:
import React from 'react'
import Dcomponent from "@/component/testContext/Dcomponent";
function NavBar() {
return (
<>
<Dcomponent compName={'TestA'} person={{name: '张三', age: 18, hobby: ['吃饭', '睡觉', '打豆豆']}}/>
</>
)
}
export default NavBar