Как вызвать обратный вызов, предоставленный свойством рендеринга, из его родительского компонента, используя хуки между рендерингами

Я пытаюсь закрыть всплывающее окно, которое можно закрыть только с помощью обратного вызова close в реквизитах рендеринга. Мне было интересно, как я могу использовать хуки или какую-то другую стратегию, чтобы сохранить эту функцию обратного вызова между рендерами, чтобы вызвать ее в useEffect. Я пытался использовать useContext безрезультатно: https://codesandbox.io/s/popover-close-from-content-y637f

В другом месте мне посоветовали следующее: codeandbox.io/s/popover-close-from-content-bss42but 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 на что я получил: «вы также можете делать такие вещи, как наличие идентификатора для текущего открытого всплывающего окна в качестве состояния, например. ноль или «ПЕРВЫЙ» или «ВТОРОЙ»

reactor 27.05.2019 22:41
...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
reactor 27.05.2019 22:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать ссылку, чтобы сохранить функцию закрытия для использования в 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.

Другие вопросы по теме