Vel*_*o89 8 reactjs react-router-dom react-hooks
由于https://github.com/remix-run/react-router/issues/8139已完成并且我们进入useBlocker了 v6,有人让它工作吗?
这是我到目前为止所得到的,几乎我陷入了我完全不明白的错误
在 App.js 中我有我的BrowserRouter并且所有东西都包含在里面
我还使用了实施者要点中的示例(我复制粘贴)
import * as React from "react";
import { useBeforeUnload, unstable_useBlocker as useBlocker } from "react-router-dom";
function usePrompt(message, { beforeUnload } = {}) {
let blocker = useBlocker(
React.useCallback(
() => (typeof message === "string" ? !window.confirm(message) : false),
[message]
)
);
let prevState = React.useRef(blocker.state);
React.useEffect(() => {
if (blocker.state === "blocked") {
blocker.reset();
}
prevState.current = blocker.state;
}, [blocker]);
useBeforeUnload(
React.useCallback(
(event) => {
if (beforeUnload && typeof message === "string") {
event.preventDefault();
event.returnValue = message;
}
},
[message, beforeUnload]
),
{ capture: true }
);
}
function Prompt({ when, message, ...props }) {
usePrompt(when ? message : false, props);
return null;
}
Run Code Online (Sandbox Code Playgroud)
然后在我的组件中我Prompt这样调用
const MyComponent = (props) => {
const [showPrompt, setShowPrompt] = useState(false)
...
return (
...
<Prompt when={showPrompt}
message="Unsaved changes detected, continue?"
beforeUnload={true}
/>
)
}
Run Code Online (Sandbox Code Playgroud)
在页面加载时MyComponent我不断收到错误
Error: useBlocker must be used within a data router. See
https://reactrouter.com/routers/picking-a-router.
at invariant (history.ts:308:1)
at useDataRouterContext (hooks.tsx:523:1)
at useBlocker (hooks.tsx:723:1)
at usePrompt (routerCustomPrompt.js:8:1)
at Prompt (routerCustomPrompt.js:37:1)
Run Code Online (Sandbox Code Playgroud)
有人进入useBlocker新版本工作了吗?
useBlocker由于我在理解如何让这个钩子和组件工作方面遇到了一些困难Prompt,因此我将详细说明我必须做的代码更改才能使其与react-router-domversion一起工作6.10.0。
首先,请参阅Using v6.4 Data APIs In v6.4的文档,其中建议使用新的数据API,特别createBrowserRouter是代替<BrowserRouter>.
根据文档,<BrowserRouter>基于的声明不“支持数据 API”,这反过来会导致Error: useBlocker must be used within a data router.
因此,在我的应用程序中,我最终替换了路线声明:
export default function App() {
return (
<YourProviders>
<BrowserRouter>
<Routes>
// your routes
</Routes>
</BrowserRouter>
</YourProviders>
);
}
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);
Run Code Online (Sandbox Code Playgroud)
和:
const router = createBrowserRouter(
createRoutesFromElements(
<Routes>
// your routes
</Routes>
)
);
export default function App() {
return (
<YourProviders>
<RouterProvider router={router} />
</YourProviders>
);
}
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);
Run Code Online (Sandbox Code Playgroud)
这最终又按Prompt预期工作了。
错误信息相当清楚。为了使用该钩子,必须在数据路由器呈现的组件中使用useBlocker它。请参阅选择路由器。
例子:
const MyComponent = (props) => {
const [showPrompt, setShowPrompt] = useState(false);
...
return (
...
<Prompt
when={showPrompt}
message="Unsaved changes detected, continue?"
beforeUnload={true}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
import {
createBrowserRouter,
createRoutesFromElements,
Route,
RouterProvider,
} from "react-router-dom";
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<Root />}>
{/* ... etc. */}
<Route path="myComponent" element={<MyComponent />} />
{/* ... etc. */}
</Route>
)
);
const App = () => <RouterProvider router={router} />;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25278 次 |
| 最近记录: |