我正在为一个反应应用程序制作一个页面,该应用程序接收数据并根据该数据生成菜单。收到的每个请求都包含任意数量的“系统”上的数据,我想为每个请求生成一个可折叠菜单。抱歉,如果以前有人问过此类问题,我搜索了谷歌,但找不到任何东西。
显然,React 中可折叠菜单的传统解决方案是创建一个变量来存储状态并使用它来切换菜单的可见性,但我不能这样做,因为我有任意数量的菜单。我尝试设置布尔字典来跟踪每个布尔字典的状态:
function Systems(props) {
const states = {};
return (
<div className={styles.formContainer}>
<p className={styles.formContainerLabel}>{props.type.toUpperCase()}</p>
{Object.keys(System_Definitions[props.type]).map((key) => {
const system = System_Definitions[props.type][key];
states[key] = false;
function toggleMenu() {states[key] = !states[key];}
return (
<div className={styles.formContainer}>
<p className={styles.formContainerLabel} onClick={toggleMenu}>
{key.toUpperCase() + ' - ' + system.label.toUpperCase()}</p>
<div id={key} className={states[key] ? '' : styles.formContainerContentHidden}>
<TextInput label={'Life'} name={'life'} placeholder={system.life} />
</div>
</div>
);
})}
</div>
);
}
但这不起作用,因为反应不跟踪状态,因此它不会在单击时更新布尔值,并且永远不会打开菜单,这是我所观察到的。我还尝试添加一个标签来向元素添加事件侦听器以切换内容:
function Systems(props) {
return (
<div className={styles.formContainer}>
<p className={styles.formContainerLabel}>{props.type.toUpperCase()}</p>
{Object.keys(System_Definitions[props.type]).map((key) => {
const system = System_Definitions[props.type][key];
return (
<div className={styles.formContainer}>
<p id={key + 'button'} className={styles.formContainerLabel}>
{key.toUpperCase() + ' - ' + system.label.toUpperCase()}</p>
<div id={key + 'content'} className={styles.formContainerContentHidden}>
<TextInput label={'Life'} name={'life'} placeholder={system.life} />
</div>
<script>
document.getElementByID({key} + 'button').addEventListener('click', () => {
document.getElementById(key + 'content').className = ''
})
</script>
</div>
);
})}
</div>
);
}
但是我收到运行时错误:“无法设置 null 的属性(设置“className”)”,我不明白,因为在加载元素之前不应执行此脚本,因为它位于有问题的元素之后。如有任何帮助,我们将不胜感激!
您给出的代码不完整,但这是我建议的要点。每个 FormContainer 管理它自己的打开/关闭状态。我确信我传递的道具不完整,所以我怀疑如果不进行一些修改它是否会起作用。
function FormContainer({system}) {
const[ open, setOpen] = useState(false)
return (
<div className={styles.formContainer}>
<p className={styles.formContainerLabel} onClick={()=> setOpen((prev)=> !prev )}>
{key.toUpperCase() + " - " + system.label.toUpperCase()}
</p>
<div
id={key}
className={open ? "" : styles.formContainerContentHidden}
>
<TextInput label={"Life"} name={"life"} placeholder={system.life} />
</div>
</div>
);
}
function Systems(props) {
return (
<div className={styles.formContainer}>
<p className={styles.formContainerLabel}>{props.type.toUpperCase()}</p>
{Object.keys(System_Definitions[props.type]).map((key) => {
const system = System_Definitions[props.type][key];
return (
<FormContainer key={key} system={system}/>
);
})}
</div>
);
}