[BUG] dcc.Dropdown: virtualized list keeps the height measured at opening when options grow while the menu is open

Đang mở
#4,131 1 bình luận 0 reaction 1 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@KoolADE85 đang làm issue này rồi.

Từ ngày 9/11/2026.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

bug P3 size: 1

Describe your context

dash                 4.5.0

Reproduced in headless Chromium (Playwright); first seen by our users on dash 4.4.1.

Describe the bug

A multi dcc.Dropdown whose options are updated by a callback while its menu is open keeps the list height it measured when the menu opened. If the menu opens while the options are few (here 1) and the callback then brings back many (here 300), the virtualized list stays one row tall (34 px) and the user has to scroll inside a single row. Closing and opening the menu again shows it at the normal height.

This happens with cascading filters: an item is chosen, the callback narrows the options to it, the user clears it with the × and opens the menu again before the callback has returned all the options.

The cause seems to be in OptionsList (components/dash-core-components/src/utils/optionRendering.tsx): the container is measured once, in a useLayoutEffect with an empty dependency array, and listHeight = Math.min(measuredHeight, options.length * defaultOptionHeight). With one option the measured height is one row, and it is never measured again when options grows.

Minimal example

import time
from dash import Dash, Input, Output, dcc, html

ALL = [f"item-{i:03d}" for i in range(300)]

app = Dash(__name__)
app.layout = html.Div(
    [dcc.Dropdown(id="dd", options=ALL, multi=True, placeholder="Pick an item")],
    style={"width": 400, "padding": 40},
)


@app.callback(Output("dd", "options"), Input("dd", "value"))
def narrow(value):
    # like a cascading filter: once an item is chosen only it is offered;
    # cleared, all 300 come back (the server takes a moment)
    time.sleep(0.5)
    return value if value else ALL


if __name__ == "__main__":
    app.run(port=8077, debug=False)

Steps:

  1. open the menu, pick item-007, close the menu (the options become ["item-007"]);
  2. click the × (Clear selection) and open the menu at once, before the callback returns;
  3. wait for the 300 options to come back.

Measured with Playwright on .dash-dropdown-content .dash-options-list-virtualized:

State list height content height
menu opened with 300 options 124 px 10494 px
step 3: menu opened with 1 option, 300 options back 34 px 10500 px
menu closed and opened again 124 px 10494 px

Expected behavior

The list height follows the options: when options changes while the menu is open, the list is measured again (for example the layout effect depending on options.length, or measuredHeight reset when the options change), so 300 options show at the normal height without closing and reopening the menu.

We work around it client-side by closing and reopening a menu whose virtualized list is shorter than three rows while its content is taller, which is what users did by hand.

Image Image
Ngôn ngữ chính
Python
Star
24.5k
Fork
2.3k
Merge trung bình
3 ngày 7 giờ
Pull request đã merge (30 ngày)
30

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của plotly/dash

Tất cả issue của plotly/dash

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.