React & MobX - диалоговое окно подтверждения, когда пользователь уходит с существующей страницы - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть что-то похожее на это:

import React from 'react';
import PropTypes from 'prop-types';
import { Prompt } from 'react-router-dom';

const ConfirmationDialog = (props) => {
  if (props.navigatingAway) {
    window.onbeforeunload = () => true;
  } else {
    window.onbeforeunload = null;
  }
  return (
    <Prompt
      when={props.navigatingAway}
      message="Are you sure?"
    />
  );
};

ConfirmationDialog.propTypes = {
  navigatingAway: PropTypes.bool.isRequired,
};

export default ConfirmationDialog;

Я пытаюсь найти лучший способ расширить это так, чтобы navigatingAway действительно что-то делал.Я не понимаю, какие критерии использовать для него, обязательно, просто он должен вызывать окно подтверждения, когда:

  • пользователь меняет URL и пытается уйти
  • aпользователь нажимает на ссылку
  • , пользователь обновляет браузер

Как лучше всего проверить изменения URL для when?

1 Ответ

1 голос
/ 03 апреля 2019

Вам не нужно придумывать способ «обнаружить», когда происходит один из ваших сценариев.

  • пользователь меняет URL-адрес и пытается отойти от него
  • пользователь обновляет браузер

Они уже обработаны благодаря присвоению обратного вызова для onbeforeunload.

  • пользователь нажимает на ссылку

Это уже обработано в силу визуализации Prompt, если вы обрабатываете навигацию с помощью react-router.

props.navigatingAway тогда лучше будет назвать props.shouldPreventNavigation или что-то в этом духе, потому что это должно сигнализировать ЕСЛИ вам следует запретить навигацию, а не навигацию.

Например, если вы ВСЕГДА хотите, чтобы перед навигацией появлялась подсказка, когда ConfirmationDialog смонтирован, то props.shouldPreventNavigation всегда должно быть истинным, и все готово. Обычный вариант использования - установить значение true, если в форме есть несохраненные данные.

Из документов на Prompt:

Вместо условного рендеринга <Prompt> за охранником, вы всегда можете отрендерить его, но передайте when={true} или when={false}, чтобы предотвратить или разрешить навигацию соответственно.

Чтобы проиллюстрировать это, следующие два фрагмента функционально эквивалентны, кроме производительности и таких:

render() {
    return (
        <Prompt
            when={this.props.navigatingAway}
            message="Are you sure?"
        />
    )
}
render() {
    if (this.props.navigatingAway) {
        return (
            <Prompt
                when={true}
                message="Are you sure?"
            />
        )
    }
    return null;
}

Если Prompt не работает должным образом из коробки, когда when={true}, то может быть, что ваша маршрутизация неправильно управляется react-router.

В качестве примечания, убедитесь, что вы учитываете, что происходит с window.onbeforeunload, если, например, ваш ConfirmationDialog размонтируется, когда ему назначен обратный вызов. Используйте соответствующие методы жизненного цикла, чтобы справиться с этим, иначе все будет странно, когда вы будете это тестировать.

...