NOTISTACK项目未渲染到提供的domroot容器中

发布于 2025-02-13 04:46:06 字数 1281 浏览 2 评论 0原文

我的目标是在Div-Container中显示Notisstack Snackbar项目,该项目可通过ScreenReaders可读。因此,我想使用 domroot SnackBarProvider的属性。

我正在使用notistack 3.0.7

我的问题现在是我的问题Div-container元素是渲染的,但不用作我的SnackBaritem的根。我只定义了一个SnackbarProvider。

index.tsx

const SnackbarProviderWrapper = () => {

    const alertContainer = React.createElement('div', {
        "aria-live": "assertive",
        className: "alert-container"
    }) as unknown as HTMLElement

    return (
        <SnackbarProvider anchorOrigin={{vertical: "bottom", horizontal: "center"}}
                          domRoot={alertContainer}
                      >
            <App/>
            {alertContainer}
        </SnackbarProvider>
    )
}


ReactDOM.render(
    <React.StrictMode>
                <SnackbarProviderWrapper/>
    </React.StrictMode>,
    document.getElementById('root')
);

My goal is it to display the notisstack snackbar items inside a div-container which is readable by screenreaders. Therefore I wanted to use the domRoot property of the SnackbarProvider.

I'am using notistack 3.0.7

My Problem is now, that the div-container element is rendered but not used as the root for my snackbaritem. I have only defined a single SnackbarProvider.

dom screenshot

index.tsx

const SnackbarProviderWrapper = () => {

    const alertContainer = React.createElement('div', {
        "aria-live": "assertive",
        className: "alert-container"
    }) as unknown as HTMLElement

    return (
        <SnackbarProvider anchorOrigin={{vertical: "bottom", horizontal: "center"}}
                          domRoot={alertContainer}
                      >
            <App/>
            {alertContainer}
        </SnackbarProvider>
    )
}


ReactDOM.render(
    <React.StrictMode>
                <SnackbarProviderWrapper/>
    </React.StrictMode>,
    document.getElementById('root')
);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

提笔落墨 2025-02-20 04:46:06

好的,我找到了解决方案。这也不是例外的“脏”,但也不干净。

首先,我将snackbarprovider移至组件中,在我的情况下,应用程序组件可以访问挂钩。
比我为容器使用一个组件,而不是react.Createlement(...)。该组件通过forwardRef将其分配元素转发。最后,我们通过usestate()钩子管理元素。

/**
 * This is the Element that will be used as a container for all notistack snackbar items
 */
const AlertContainer = React.forwardRef<HTMLDivElement>((props, ref) => (
    <div ref={ref} className="alert-container" aria-live={"assertive"}>
        {props.children}
    </div>
));

function App() {
    const [alertContainer, setAlertContainer] = useState<HTMLDivElement | null>(null)

    return (
        <>
            <AlertContainer ref={setAlertContainer}/>
            {alertContainer ?
                <SnackbarProvider anchorOrigin={{vertical: "bottom", horizontal: "center"}}
                                  domRoot={alertContainer}>
                    <main/>
                </SnackbarProvider>
                : null /* we must have this conditon to render the DOM once so our AlertContainer is present*/}
        </>
    );
}

您可能会问为什么不使用useref()挂钩?那是因为在使用容器组件之前,树必须至少渲染一次。
因此,我们还添加了第一个渲染中返回null的条件。如果我们没有这个,我们的AlertContainer组件尚不存在,DOMRoot将是null

奇怪的是,Notistack期望属性domroot的已经初始化的HTMLELLENT。这禁止我们在此处使用常规参考。
这尤其奇怪,因为无需使用现有的DOM元素。当必须显示警报/snackbaritem时,必须存在该元素,而不是以前。

Ok I found a workaround solution. It is no exceptional "dirty" but not clean either.

First I moved the SnackbarProvider to a component, in my case the App component to have access to hooks.
Than I used a component for my container instead of React.createElement(...). This component forwards its div-Element via forwardRef. Finaly we manage the Element via a useState() hook.

/**
 * This is the Element that will be used as a container for all notistack snackbar items
 */
const AlertContainer = React.forwardRef<HTMLDivElement>((props, ref) => (
    <div ref={ref} className="alert-container" aria-live={"assertive"}>
        {props.children}
    </div>
));

function App() {
    const [alertContainer, setAlertContainer] = useState<HTMLDivElement | null>(null)

    return (
        <>
            <AlertContainer ref={setAlertContainer}/>
            {alertContainer ?
                <SnackbarProvider anchorOrigin={{vertical: "bottom", horizontal: "center"}}
                                  domRoot={alertContainer}>
                    <main/>
                </SnackbarProvider>
                : null /* we must have this conditon to render the DOM once so our AlertContainer is present*/}
        </>
    );
}

You might ask why not use a useRef() hook? That is because the Tree must render at least once before using the container component.
For this reason we have also added the condition that returns null on the first render. If we don't have this our AlertContainer componente is not yet present in the DOM and domRoot will be null.

It is strange that notistack expects an already initialized HTMLElement for the property domRoot. This prohibits us from using a regular ref here.
This is especially strange since there is no need to use an existing DOM element. The element must be present when an Alert/SnackbarItem must be displayed, not before.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文