我正在尝试将动态标签命名系统从React转换成类似 hook 的方法,我正在做的是首先导入和导出一些组件,以便可以拉动它们一次全部放在一个数组上,像这样:
import Component1 from './Component1/Component1'
import Component2 from './Component2/Component2'
export {
Component1,
Component2
}
然后我像这样加载它们:
import { useState, useEffect } from "react";
import * as Components from './../AllComponents/Components'
function importHook() {
const [states, setStates] = useState({
components: [],
currentComponent: 0
})
useEffect(() => {
Object.entries(Components).forEach(component => {
setStates(prevState => ({ components: [...prevState.components, component[1]]}))
})
}, []) // Look's into Components and adds every component to the 'components' array so that I can use that array in the next step.
return states;
}
export default importHook
然后我继续这样做:
import React from 'react'
import './MainComponent.scss'
import importHook from '../../importHook'
function MainComponent() {
const { components, currentComponent } = importHook() // Pull and set the values using the hook
const TagName = components[currentComponent] // Created the tag name by targeting the first function, seeing as currentComponent should be 0 at the time
console.log('Tag: ' + TagName) // undefined
return (
<div className="h-100">
<TagName /> // crashes everything
</div>
)
}
export default MainComponent
所以我发现<TagName />
使所有内容崩溃的原因是因为某些内容运行了两次。
如果删除<TagName />
,以便可以从console.log
获取输出,并将currentComponent
内的const TagName
更改为0
,则会注意到第一个运行console.log
的时间将返回undefined
,而第二次运行将返回存储在数组内部的实际函数。
所以实际上我的问题是,为什么/什么执行两次?我有个主意,我假设是因为forEach
会添加到数组中或类似的东西,但我不确定。
可以做什么,以便我们可以在返回此处之前准备好所有值?我还没有尝试过,但是我想我可以引入一个if statement
来检查变量是否为空,如果是,则显示某种加载屏幕或坐立不安,但这看起来并不像对我而言,这是最好的解决方案,我知道有很多方法可以做某事,但并非所有方法都很好,因为我对这一切真的很陌生,因此阅读/询问更好。
关于阅读的部分,找不到关于解决此问题或我提到的实现的太多信息,我尝试了useEffect,useCallback和其他类似方法,不确定是否我做错了... < / p>