Prevent Transition với React router dom
Bài đăng này đã không được cập nhật trong 3 năm
Hi mọi người. Tình hình là mình vừa mới làm xong task "hiển thị thông báo cho người dùng lúc chuyển trang" nên ở bài viết này mình sẽ chia sẻ hai cách mà mình tìm hiểu được nhé. OK go go
Cách 1: Sử dụng Prompt
<Prompt
when={formIsHalfFilledOut}
message="Are you sure you want to leave?"
/>
Nguồn: https://reactrouter.com/core/api/Prompt
Trong đó message có thể là string
hoặc function
export interface PromptProps {
message: string | ((location: H.Location, action: H.Action) => string | boolean);
when?: boolean;
}
Ví dụ:
function BlockingForm() {
let [isBlocking, setIsBlocking] = useState(false);
return (
<form
onSubmit={event => {
event.preventDefault();
event.target.reset();
setIsBlocking(false);
}}
>
<Prompt
when={isBlocking}
message={location =>
`Are you sure you want to go to ${location.pathname}`
}
/>
<p>
Blocking?{" "}
{isBlocking ? "Yes, click a link or the back button" : "Nope"}
</p>
<p>
<input
size="50"
placeholder="type something to block transitions"
onChange={event => {
setIsBlocking(event.target.value.length > 0);
}}
/>
</p>
<p>
<button>Submit to stop blocking</button>
</p>
</form>
);
}
Nguồn: https://reactrouter.com/web/example/preventing-transitions
Để customize Prompt
, mọi người có thể tham khảo ví dụ này nhé: https://codesandbox.io/s/myw173jyq8
Cách 2: Sử dụng history.block
Cú pháp của nó kiểu như sau:
// Register a simple prompt message that will be shown the
// user before they navigate away from the current page.
const unblock = history.block('Are you sure you want to leave this page?');
// Or use a function that returns the message when it's needed.
history.block((location, action) => {
// The location and action arguments indicate the location
// we're transitioning to and how we're getting there.
// A common use case is to prevent the user from leaving the
// page if there's a form they haven't submitted yet.
if (input.value !== '') return 'Are you sure you want to leave this page?';
});
// To stop blocking transitions, call the function returned from block().
unblock();
Nguồn: https://github.com/ReactTraining/history/blob/v4/docs/Blocking.md
Lưu ý: ở đây mình sử dụng history v4
mọi người nhé, v5
sẽ ko hoạt động đúng, đều cũng tương tự, mọi người tự tìm hiểu thêm nhé ^^
Mình sẽ sửa lại code ở cách trên như sau:
function BlockingForm() {
const history = useHistory()
let [isBlocking, setIsBlocking] = useState(false);
useEffect(() => {
let unblock;
if (isBlocking) {
unblock = history.block((location) => {
if (window.confirm(`Are you sure you want to go to ${location.pathname}`)) {
unblock();
return true;
}
return false;
});
} else {
if (unblock) unblock();
}
return unblock;
}, [isBlocking])
return (
<form
onSubmit={event => {
event.preventDefault();
event.target.reset();
setIsBlocking(false);
}}
>
<p>
Blocking?{" "}
{isBlocking ? "Yes, click a link or the back button" : "Nope"}
</p>
<p>
<input
size="50"
placeholder="type something to block transitions"
onChange={event => {
setIsBlocking(event.target.value.length > 0);
}}
/>
</p>
<p>
<button>Submit to stop blocking</button>
</p>
</form>
);
}
Kết
Bài viết hôm nay đến đây thôi, hy vọng sẽ giúp ích được cho mọi người trong những dự án sắp tới. Chúc mọi người thành công
All rights reserved