我遇到了一个非常令人困惑的问题,即即使数据始终加载到控制台日志中,数据也无法始终加载到 UI 中进行反应。
我正在尝试使用数据库中存储的 ui 规范数据在 React 中动态生成表单,以了解表单元素的外观和行为。如果该元素是选择下拉菜单,我想根据选择元素的数据中指定的内容,从数据库的不同表和字段中动态提取列表选项的数据。我正在尝试一种方法,将所有列表存储在一个数组中,然后在 React 中创建表单时循环遍历该数组(不确定这是否是最好的方法)。
加载通用表单数据时,一切正常且一致。当尝试通过提取每个列表的数据来动态创建下拉菜单时,有时会起作用,有时则不起作用。例如,包含下拉菜单的数组有时会显示 2 个列表,有时会显示 1 个列表,即使控制台日志始终显示数组中存储有 2 个列表,这是正确的。
非常感谢任何见解或建议。
这是我的代码:
const App = (props) => {
const formName="user_form"
const [formElements, setFormElements] = useState([]);
const [dropdownLists, setDropdownLists] = useState([])
const getFormData = async () => {
try {
const response = await axios.get([myurl]);
const data = await response.data;
setFormElements(data); //<--This works consistently
let tempDropdownLists = []
await data.map(item=> {
if(item.ui_component_type === "select"){
const getListItems = async (req, res)=>{
try{
const query = `SELECT DISTINCT ${item.ui_data_field} from
${item.ui_data_table}`
const response = await axios.post([myurl],
{query});
const listItems = await response.data
console.log(listItems) //<--This always works consistently. I have 2 dropdown lists that I am storing for this form.
let listData = {name:`${item.ui_id}_list`, listItems: listItems} //<--This is how i'm trying to store each dropdown list for each drop down menu. I want to later dynamically filter this array and lookup up the list based on the select drop down menu that is being rendered
tempDropdownLists.push(listData)
console.log(tempDropdownLists) //<--this consistently shows the right lists on every refresh
setDropdownLists(tempDropdownLists) //<--This should work but when rendering the page, I don't consistently see the dropdownlists
}catch(error){
console.log(error)
}
}
getListItems();
}
})
} catch (error) {
console.log(error)
}
};
useEffect(() => {
getFormData();
}, [props]);
return(
<div className="d-flex flex-column">
<p>{JSON.stringify(dropdownLists.length)}</p> //<--This my check but doesn't always show the right number of elements in the array. Sometimes it shows 1 element (list), sometimes it shows 2, even though there are always 2 elements in the array in console.log. Why?
<form>
{formElements.map((item,index)=>(
<div key={index} className="form-floating m-3">
{item.ui_component_type == "input" &&
<><input id={item.ui_id} name={item.ui_name} className={item.ui_classname </input>
<label className="form-label">{item.ui_label}</label></>
}
{item.ui_component_type == "select" &&
<>
<select id={item.ui_id} name={item.ui_name} className={item.ui_classname}>
//Code breaks here below. React doesn't see all of the dropdown list in the array even though they exist in console log.
{(dropdownLists.filter(list=>list.name===`${item.ui_id}_list`) [0].listItems).map((listItem, listItemIndex)=>(
<option
key={listItemIndex}
value={listItem}
>
{listItem}
</option>)
</select>
<label className="form-label">{item.ui_label}</label>
</>}
</div>
))}
</form>
</div>
)
}
export default App
尝试使用状态更新的函数形式来确保您正在使用最新的状态。这是一个例子,你可以用这个替换你的 setDropdownLists
setDropdownLists(prevDropdownLists => [...prevDropdownLists, ...tempDropdownLists]);
此外,为了提高可读性,我建议您将
getListItems
移到外面,并使用 useCallback