You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态加载选项至Multiselect组件首次加载失效问题排查

问题:multiselect-react-dropdown动态加载选项失败

使用multiselect-react-dropdown实现多选框,选项通过API动态获取,但多选框在API请求完成前就已渲染,导致选项无法加载。尝试通过useEffect延迟组件渲染、添加businessUnits &&判断渲染时机均无效,控制台显示businessUnits数组先打印两次空值,之后才出现包含有效数据的数组。

解决方案

1. 修正初始状态与渲染判断

将businessUnits的初始状态设为null而非空数组,这样businessUnits && ...的条件判断会在API未返回数据时不渲染多选框组件,避免组件提前接收空数组完成渲染。

2. 修复多选框选中状态的更新逻辑

原组件中selectedValues仅初始化但未设置更新方法,导致选中状态无法同步,需添加对应的状态更新函数并绑定到多选框的onSelect和onRemove事件。

3. 匹配displayValue属性与选项结构

转换后的选项对象是{ label: item.name, value: item.code },因此displayValue需设为"label"而非原代码中的"name",确保下拉列表能正确显示选项文本。

4. 优化API请求写法

使用async/await替代链式then,让代码更简洁易读,同时统一错误处理逻辑。


修改后的代码

LotList主组件

import React, { useState, useEffect } from 'react';
import { Container, Row, Col, Form } from 'react-bootstrap';
import DateRange from '../DateRange';
import SiteComponentLoader from '../SiteComponentLoader';
import MultiselectBox from '../Utilities/MultiselectBox';
import { fetchDataAuthenticated } from '../Utilities/HttpUtils';
import useAlert from '../Alerts/useAlert';

function LotList({ status }) {
    status ??= "";

    const defaultDateRange = {
        from: null,
        to: null
    };

    const { setAlert } = useAlert();
    // 初始状态设为null,确保条件判断生效
    const [businessUnits, setBusinessUnits] = useState(null);
    const option = item => ({ label: item.name, value: item.code });

    useEffect(() => {
        async function getBusinessUnits() {
            try {
                const response = await fetchDataAuthenticated("api/v1/businessunit");
                if (!response.ok) throw new Error("Failed to get business units");
                const data = await response.json();
                setBusinessUnits(data.map(option));
            } catch (error) {
                setAlert("danger", "Error", error.message);
            }
        }

        getBusinessUnits();
    }, []);

    const [dateFilter, setDateFilter] = useState(defaultDateRange);
    const [includeGraded, setIncludeGraded] = useState(false);

    const handleIncludeGraded = (e) => {
        setIncludeGraded(e.target.checked);
    }


    return (
        <Container fluid>
            <Row className="d-flex align-items-center mb-3">
                <Col className="d-flex justify-content-start">
                    <DateRange dateFilter={dateFilter} setDateFilter={setDateFilter} />
                </Col>
                <Col className="d-flex justify-content-middle">
                    {/* 数据返回后再渲染多选框 */}
                    {businessUnits && <MultiselectBox businessUnits={businessUnits} />}
                </Col>
                <Col className="d-flex justify-content-end pt-2">
                    <Form.Check 
                        type="checkbox" 
                        onChange={handleIncludeGraded} 
                        className="me-2" 
                        style={{ marginTop: "-0.5rem" }} 
                    />
                    <Form.Label>Include graded items?</Form.Label>
                </Col>
            </Row>
            <Row>
                <SiteComponentLoader 
                    component="./Pages/LotListTable" 
                    site="SCP" 
                    tableFilters={{ status, dateFilter, includeGraded }} 
                />
            </Row>
        </Container>
    );
}

export default LotList;

MultiselectBox组件

import React, { useState } from 'react';
import { Form, Row } from 'react-bootstrap';
import Multiselect from 'multiselect-react-dropdown';

function MultiselectBox({ businessUnits }) {
    // 添加状态更新函数,支持选中/移除选项
    const [selectedValues, setSelectedValues] = useState([]);

    return (
        <Form.Group as={Row} className="me-3" controlId="title">
            <Form.Label>Business Units: </Form.Label>
            <Multiselect
                options={businessUnits}
                selectedValues={selectedValues}
                onSelect={setSelectedValues}
                onRemove={setSelectedValues}
                displayValue="label" // 匹配转换后的选项属性
                loading={!businessUnits} // 根据数据状态控制loading显示
            />
        </Form.Group>
    );
}

export default MultiselectBox;

内容的提问来源于stack exchange,提问作者shizz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:42:31