允许应用程序阻止 SPA 内的导航,并向用户显示一个确认对话框以确认导航。主要用于避免丢失填写了一半的表单数据。这不处理硬刷新或跨域导航。
该钩子返回的 Blocker
对象具有以下属性
state
unblocked
- 阻塞器处于空闲状态,未阻止任何导航blocked
- 阻塞器已阻止一次导航proceeding
- 阻塞器正在从一次被阻止的导航中继续进行location
blocked
状态时,这代表我们阻止导航到的 Location
。当处于 proceeding
状态时,这是在调用 blocker.proceed()
后正在导航到的位置。proceed()
blocked
状态时,您可以调用 blocker.proceed()
来继续前往被阻止的位置。reset()
blocked
状态时,您可以调用 blocker.reset()
将阻塞器返回到 unblocked
状态,并让用户停留在当前位置。// Boolean version
let blocker = useBlocker(value !== "");
// Function version
let blocker = useBlocker(
({ currentLocation, nextLocation, historyAction }) =>
value !== "" &&
currentLocation.pathname !== nextLocation.pathname
);
function useBlocker(shouldBlock: boolean | BlockerFunction): Blocker
一个布尔值或一个返回布尔值的函数,用于指示是否应阻止导航。函数格式接收一个包含潜在导航的 currentLocation
、nextLocation
和 historyAction
的对象参数。
一个具有状态和重置功能的 Blocker
对象
import { useCallback, useState } from "react";
import { BlockerFunction, useBlocker } from "react-router";
export function ImportantForm() {
const [value, setValue] = useState("");
const shouldBlock = useCallback<BlockerFunction>(
() => value !== "",
[value]
);
const blocker = useBlocker(shouldBlock);
return (
<form
onSubmit={(e) => {
e.preventDefault();
setValue("");
if (blocker.state === "blocked") {
blocker.proceed();
}
}}
>
<input
name="data"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<button type="submit">Save</button>
{blocker.state === "blocked" ? (
<>
<p style={{ color: "red" }}>
Blocked the last navigation to
</p>
<button
type="button"
onClick={() => blocker.proceed()}
>
Let me through
</button>
<button
type="button"
onClick={() => blocker.reset()}
>
Keep me here
</button>
</>
) : blocker.state === "proceeding" ? (
<p style={{ color: "orange" }}>
Proceeding through blocked navigation
</p>
) : (
<p style={{ color: "green" }}>
Blocker is currently unblocked
</p>
)}
</form>
);
}