Я только что обновил Router v6.5.0 до 6.26.0.
У меня есть форма, и я хочу перехватывать любые изменения местоположения в веб-браузере, если форма не была сохранена.
Например, если я нахожусь на странице /profile
и пытаюсь перейти на /about
, я хочу отобразить пользовательское модальное окно, которое спрашивает меня, хочу ли я сохранить свой прогресс.
Нажав ДА или НЕТ, я хотел бы перейти к намеченному месту.
@DerekRoberts Код формы на самом деле не нужен. Сейчас смотрю на useLocation
и useHistory
, но не знаю, где искать. Я не хочу вручную назначать обработчики onClick
всему на экране.
@DerekRoberts Каждый раз, когда местоположение вот-вот изменится, я хочу перехватить это изменение и отменить его, а затем вручную перемещаться на основе пользовательской логики. Выполнение чего-то вроде window.addEventListener('beforeunload', handleBeforeUnload)
не дает того, что я хочу, потому что оно срабатывает только тогда, когда я делаю что-то вроде перезагрузки.
ок, я бы предложил history.block
с тем, что у вас сейчас есть в форме.
@DerekRoberts На самом деле я использую Router v6, и похоже, что useNavigate заменил useHistory
Я ссылаюсь на документ там написано, что useNavigate заменил useHistory.
В React Router есть крючок useBlocker, позволяющий делать именно то, что вы хотите:
Крючок
useBlocker
позволяет запретить пользователю переходить из текущего местоположения и предоставить ему собственный пользовательский интерфейс, позволяющий подтвердить навигацию.
const Form = () => {
...
const blocker = useBlocker(({ currentLocation, nextLocation }) => (
currentLocation.pathname !== nextLocation.pathname
&& /* Other conditions */
));
return (
...
{blocker.state === "blocked" && (
<div>
<p>Are you sure you want to leave?</p>
<button onClick = {() => blocker.proceed()}>
Proceed
</button>
<button onClick = {() => blocker.reset()}>
Cancel
</button>
</div>
)}
...
);
}
Я получаю эту ошибку: В моем App.jsx есть маршруты между тегами useBlocker must be used within a data router
.
@Dex Ах, ну, я думаю, это означает, что эта функция доступна только с маршрутизаторами, поддерживающими новые API-интерфейсы данных .
Подвох: если сработает блокировщик, а вы не позвоните blocker.reset()
, вы получите эту ошибку A router only supports one blocker at a time
привет ох, я полагаю, тебе нужен фрагмент кода? не могли бы вы поделиться кодом формы?