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

在React-bootstrap Modal中使用useCombobox触发控制台错误的问题

React-Bootstrap Modal内使用downshift useCombobox触发控制台错误的解决办法

问题场景

在React-Bootstrap的Modal组件内使用downshift的useCombobox钩子时,控制台会抛出以下错误:

downshift: You forgot to call the getInputProps getter function on your component / element.
downshift: You forgot to call the getMenuProps getter function on your component / element.
downshift: The ref prop "undefined" from getInputProps was not applied correctly on your element.
downshift: The ref prop "undefined" from getMenuProps was not applied correctly on your element.

虽然表单功能最终正常运行,但错误会在页面加载时触发。核心原因是React-Bootstrap的Modal默认在隐藏状态下不会渲染内部DOM,此时useCombobox已经完成初始化,但对应的getInputProps、getMenuProps等getter函数并未被调用(因为Modal内的组件还未挂载),downshift的内部检测机制会认为钩子已初始化但必要的props未被应用,从而抛出错误;直到Modal显示、内部组件渲染后,这些getter才被执行,但错误已经输出。

原相关代码如下:

const {
    getInputProps: getInputPropsTag,
    getItemProps: getItemPropsTag,
    getMenuProps: getMenuPropsTag,
    openMenu: openMenuTag,
    isOpen: isOpenTag
} = useCombobox({
    items: __itemsTags,
    onInputValueChange({ inputValue }) { _handleChangeTag(inputValue) },
    onSelectedItemChange: ({ selectedItem: __selectedItem }) => _handleSelectTag(__selectedItem),
    itemToString: item => (item ? item.value : '')
});

<Modal className='_blogModal' show={_showModal} onHide={() => setShowModal(false)} centered>
    <Modal.Header closeButton>
        <Modal.Title className='d-flex'>
            <Dropdown
                show={_showFilterDropdown}
                onMouseEnter={() => {
                    setShowFilterDropdown(true);
                }}
                onMouseLeave={() => {
                    setShowFilterDropdown(false);
                }}
            >
                <Dropdown.Toggle as='span'></Dropdown.Toggle>
                <Dropdown.Menu className='border-0 border-top rounded-0'>
                    <Form className='d-flex flex-column'>
                        <Dropdown.Item as='span' eventKey='4'>
                            <Controller
                                name='_tagInput'
                                control={control}
                                render={({ field }) => (
                                    <Form.Group
                                        controlId='_tagInput'
                                        className={`_formGroup _searchGroup ${_tagFocused || !_.isEmpty(field.value) ? 'focused' : ''}`}
                                    >
                                        <FloatingLabel
                                            label='Tags.'
                                            className='_formLabel _autocomplete'
                                        >
                                            <FontAwesomeIcon icon={faHashtag} />
                                            <Form.Control
                                                {...getInputPropsTag({
                                                    ...field,
                                                    onFocus: _handleFocusTag,
                                                    onBlur: _handleBlurTag
                                                })}
                                                placeholder='Tags.'
                                                autoComplete='new-password'
                                                type='text'
                                                className={`_formControl border border-0 rounded-0 ${!_.isEmpty(_typedCharactersTag) ? '_typing' : ''}`}
                                                name='_tagInput'
                                            />
                                        </FloatingLabel>
                                        <SimpleBar className='_SimpleBar' style={{ maxHeight: '40vh' }} forceVisible='y' autoHide={false}>
                                            <ListGroup
                                                className='border border-0 rounded-0 d-block'
                                                {...getMenuPropsTag()}
                                            >
                                                {
                                                    isOpenTag &&
                                                    _.map(
                                                        __itemsTags
                                                        , (item, index) => {
                                                            return (
                                                                <ListGroup.Item
                                                                    className='border border-0 rounded-0 d-flex align-items-center'
                                                                    {...getItemPropsTag({
                                                                        key: index,
                                                                        index,
                                                                        item
                                                                    })}
                                                                >
                                                                    <FontAwesomeIcon icon={faHashtag} className='me-2' />
                                                                    {item.value}
                                                                </ListGroup.Item>
                                                            )
                                                        }
                                                    )
                                                }
                                            </ListGroup>
                                        </SimpleBar>
                                    </Form.Group>
                                )}
                            />
                        </Dropdown.Item>
                    </Form>
                </Dropdown.Menu>
            </Dropdown>
        </Modal.Title>
    </Modal.Header>
</Modal>

解决方案

1. 条件初始化useCombobox

只有当Modal处于显示状态时才初始化useCombobox,避免在Modal未渲染时提前创建钩子实例,从根源上避免downshift的错误检测:

// 仅在Modal显示时初始化useCombobox
const comboboxProps = _showModal ? useCombobox({
    items: __itemsTags,
    onInputValueChange({ inputValue }) { _handleChangeTag(inputValue) },
    onSelectedItemChange: ({ selectedItem: __selectedItem }) => _handleSelectTag(__selectedItem),
    itemToString: item => (item ? item.value : '')
}) : {};

const {
    getInputProps: getInputPropsTag,
    getItemProps: getItemPropsTag,
    getMenuProps: getMenuPropsTag,
    openMenu: openMenuTag,
    isOpen: isOpenTag
} = comboboxProps;

2. 确保ref正确传递

在合并getInputProps和React Hook Form的field props时,注意顺序:先展开field,再展开getInputPropsTag的结果,确保downshift返回的ref不会被覆盖,解决"ref prop undefined"的错误:

<Form.Control
    {...field}
    {...getInputPropsTag({
        onFocus: _handleFocusTag,
        onBlur: _handleBlurTag
    })}
    placeholder='Tags.'
    autoComplete='new-password'
    type='text'
    className={`_formControl border border-0 rounded-0 ${!_.isEmpty(_typedCharactersTag) ? '_typing' : ''}`}
    name='_tagInput'
/>

3. 可选:Modal显示后延迟初始化逻辑

如果需要在Modal显示后执行菜单相关的初始化操作,比如自动打开菜单,可以用useEffect监听Modal的显示状态:

import { useEffect } from 'react';

useEffect(() => {
    if (_showModal && openMenuTag) {
        // 根据需求执行初始化,比如打开菜单
        // openMenuTag();
    }
}, [_showModal, openMenuTag]);

内容的提问来源于stack exchange,提问作者Zakariae Bou-taleb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:55:21