Я пытаюсь закрыть всплывающее окно, которое можно закрыть только с помощью обратного вызова close в реквизитах рендеринга. Мне было интересно, как я могу использовать хуки или какую-то другую стратегию, чтобы сохранить эту функцию обратного вызова между рендерами, чтобы вызвать ее в useEffect. Я пытался использовать useContext безрезультатно: https://codesandbox.io/s/popover-close-from-content-y637f
...you probably don't need multiple open at once, so reducing the state to a single value might be desirable. you could try to abstract out a component that manages the popup state, and gives the child a function like onAction(promise). and the reusable popup component can manage if it's open, and set itself to closed when the promise resolves, so you don't need to repeat that logic everywhere
Вы можете использовать ссылку, чтобы сохранить функцию закрытия для использования в useEffect. Вот рабочий codeandbox: https://codesandbox.io/s/popover-close-from-content-sgmgs
import React, { useEffect, useState, useRef } from "react";
import { Block } from "baseui/block";
import { Button } from "baseui/button";
import { StatefulPopover } from "baseui/popover";
export default () => {
const closeRef = useRef();
const [state, setState] = useState({ isSaving: false });
useEffect(() => {
if (state.isSaving) {
const timeout = setTimeout(() => {
console.info("closing", closeRef.current);
// close popover from here
closeRef.current && closeRef.current();
setState({ isSaving: false });
}, 5000);
return () => {
clearTimeout(timeout);
};
}
}, [state.isSaving]);
const onSave = () => {
console.info("save btn clicked");
setState({ isSaving: true });
};
return (
<div>
<StatefulPopover
content = {(
{ close } // I need to call close per this library's API to close
) => {
closeRef.current = close;
return (
<Block padding = "scale500" maxWidth = "300px">
<Block paddingBottom = "scale400">
content render prop is passed a <code>close()</code> callback so
it you can manually trigger popover close from within
</Block>
<Button isLoading = {state.isSaving} onClick = {onSave}>
Save
</Button>
</Block>
);
}}
>
<Button>Click Me</Button>
</StatefulPopover>
</div>
);
};
Контекст не работает, как вы ожидаете, потому что вы пытаетесь получить доступ к контексту, используя useContext
вне провайдера. Чтобы получить доступ к значению от провайдера, хуки useContext
должны использоваться внутри дочернего компонента контекстного провайдера. В противном случае useContext
просто получит значение по умолчанию, переданное в createContext
.
В другом месте мне посоветовали следующее: codeandbox.io/s/popover-close-from-content-bss42
but the real correct solution is to not have this StatefulPopover be stateful if you need to control it from outside. you should be telling it if it's open or not with a prop
. Я также спросил:I was planning on building a menu bar with dropdown menus made up of these popovers and was wondering how many of these fileMenuIsOpen, etc would be too much
на что я получил: «вы также можете делать такие вещи, как наличие идентификатора для текущего открытого всплывающего окна в качестве состояния, например. ноль или «ПЕРВЫЙ» или «ВТОРОЙ»