Race Condition: Material-UI Select 在执行条件渲染生成 MenuItem 时认为值超出范围

Race Condition: Material-UI Select thinks value is out of range when performing conditional rendering to generate MenuItems

我正在使用 Material-UI 为我的仪表板创建一些 Select。 Select 中的菜单项(选项)是使用条件渲染生成的。我根据从远程 API 检索的数组中的一组选项列表使用映射到 return MenuItems。 Select 的值也是根据从远程 API 检索到的值确定的。根据 API 响应,默认值更新为实际值。

快速浏览一下组件的相关部分:

            <Select
            MenuProps={{
                className: classes.selectMenu,
            }}
            classes={{
                select: classes.select,
            }}
            id={id}
            name={name}
            defaultValue={defaultValue}
            value={value}
            onChange={onChange}
        >
            <MenuItem
                disabled
                classes={{
                    root: classes.selectMenuItem,
                }}
                value={0}
            >
                {labelText}
            </MenuItem>
            {selectOptions.map(opt =>
                <MenuItem
                classes={{
                    root: classes.selectMenuItem,
                    selected: classes.selectMenuItemSelected,
                }}
                value={opt.IDX}
                key={`${name}${opt.IDX}`}
            >
                {opt.Name}
            </MenuItem>)}
        </Select>

每个选项都有一个 IDX 属性 和一个名称 属性。因此,例如,下拉列表中的用户列表将显示 Bob、Sally、Jeff,并且相对于 Bob、Sally 和 Jeff 的 ID 号,值将是 1、2、3 等。如您所见,有一个指定值为 0 的默认选项和一个 defaultValue 属性。

我在 JS 控制台中收到以下警告:

You have provided an out-of-range value `1` for the select component.
Consider providing a value that matches one of the available options or ''.
The available values are `0`.

我只能假设是因为 React 直到渲染后才知道有条件渲染的 MenuItem,此时远程 API 可能已经响应并且值Select 组件已经设置为默认值以外的值。

这似乎不会以任何方式影响代码功能,但它是一种竞争条件,我不喜欢它。有没有一种方法可以执行检查以确保我的组件具有所有可用的 MenuItem 并在设置父 select 组件的值之前设置它们的值?

我正在考虑以某种方式在 JSX 中设置类似 isFullyProcessed 布尔值的东西,然后使用它。

编辑:

以下是我在父页面上获取数据的方式。时间表和组是选项数据,用户是价值的来源。

   useEffect(() => {
    axios.get(`${server}${uPath}/data`).then((response) => {
      const parsed = JSON.parse(response.data);
      setSchedules(parsed.schedules);
      setGroups(parsed.groups);
      setUser(parsed.user);

如评论所述,通过等待渲染直到从 API 检索到所有数据来解决此问题。显然,即使 API 调用设置值和设置菜单选项是在同一个函数中完成的,因为我使用两个独立的状态来存储此信息,所以可以在不同的渲染中设置值循环比呈现菜单选项。

我添加了一个 isLoading 布尔值并等待使用效果 return 来自 API 的数据,这解决了问题。 Quick tutorial here.