React动态生成组件状态设置:Strapi自定义Combobox选中值问题
解决Strapi自定义Combobox动态设置选中值的问题
问题描述
在Strapi应用中复用外部组件创建自定义Combobox,选项从服务器动态获取。静态场景下直接使用
useState(valueSelected)可行,但动态生成时因选项未加载出现“Failed to get 'props' property of undefined”错误;若在返回组件前调用setValue,会触发“Too many re-renders”循环,求可行方案。
原代码:
import React, { useState, useEffect } from "react"; import { Combobox, ComboboxOption } from "@strapi/design-system"; export default function ComboboxCustom({ valuesList, valueSelected }) { const [value, setValue] = useState(''); const combo = (<Combobox label="Country" value={value} onChange={setValue}> {valuesList.map((entry) => { return( <ComboboxOption value="{entry.id}">{entry.name}</ComboboxOption> ); })} </Combobox>); // setValue(valueSelected) return combo; }
解决方案
核心思路
- 避免直接在组件主体内调用
setValue,改用useEffect监听依赖变化,仅在符合条件时更新选中值 - 初始化状态和渲染时做空值校验,防止选项未加载时触发报错
- 修复
ComboboxOption的value绑定错误(原代码用字符串包裹entry.id,导致值为字面量"{entry.id}"而非实际ID)
修改后的代码
import React, { useState, useEffect } from "react"; import { Combobox, ComboboxOption } from "@strapi/design-system"; export default function ComboboxCustom({ valuesList = [], // 给默认空数组,避免map时报错 valueSelected }) { // 初始化状态时,仅在valueSelected有效时赋值,否则为空 const [value, setValue] = useState(valueSelected || ''); useEffect(() => { // 当valuesList加载完成且valueSelected有效时,更新选中值 if (valuesList.length > 0 && valueSelected) { // 可选:额外校验valueSelected是否存在于选项中,避免无效值 const optionExists = valuesList.some(entry => entry.id === valueSelected); if (optionExists) { setValue(valueSelected); } } }, [valuesList, valueSelected]); // 依赖项:valuesList或valueSelected变化时触发 return ( <Combobox label="Country" value={value} onChange={setValue}> {/* 渲染前先判断valuesList是否存在,避免空值map */} {valuesList?.map((entry) => ( <ComboboxOption key={entry.id} value={entry.id}> {entry.name} </ComboboxOption> ))} </Combobox> ); }
关键说明
- 给
valuesList设置默认空数组,同时在map前用可选链?.,防止选项未加载时调用map报错 - 使用
useEffect监听valuesList和valueSelected,只有当选项加载完成且选中值有效时才更新状态,彻底避免重渲染循环 - 增加选项存在性校验,防止传入的
valueSelected不在选项列表中导致的异常 - 修复
ComboboxOption的value绑定错误,同时添加key属性符合React列表渲染规范
内容的提问来源于stack exchange,提问作者Evgeny
相关产品推荐
相关产品推荐

