SolidJS Router useNavigate() 抛出: 错误:确保您的应用程序包装在 <Router /> 中



即使我的应用程序被包裹在路由器标签中,当我使用useNavigate()<Navigate />元素时,我得到相同的错误login.tsx:27 Error: Make sure your app is wrapped in a <Router />

这是我的索引。tsx

/* @refresh reload */
import { render } from 'solid-js/web';
import './index.css';
import App from './App';
import { Router } from 'solid-app-router';
render(
() => (
<Router>
<App />
</Router>
),
document.getElementById('root') as HTMLElement
)

App.tsx

const App: Component = () => {
return (
<>
<Routes>
<Route path="/" component={Landing} />
<Route path="/dashboard" component={Dashboard} />
</Routes>
</>
)
}

Login组件的父级登陆组件

import { useNavigate } from 'solid-app-router'
import { Component, createSignal, Show, onMount } from 'solid-js'
import { getIsValidSession } from '../services/session'
import '../styling/landing.css'
import CreateAccount from './landing/create-account'
import Login from './landing/login'
const Landing: Component = () => {
const [displayLogin, setDisplayLogin] = createSignal(true)
return (
<div class="landing text-center">
<main class="form-signin">
<img
class="mb-4"
src="src/assets/original/tracker-image.png"
alt=""
width="72"
height="85"
/>
<Show when={displayLogin()} fallback={<CreateAccount />}>
<Login />
</Show>
<Show
when={displayLogin()}
fallback={
<button
class="w-100 btn btn-lg btn-primary mt-3"
onClick={toggleDisplay}>
Login Existing User
</button>
}>
<button
class="w-100 btn btn-lg btn-primary mt-3"
onClick={toggleDisplay}>
Create Account
</button>
</Show>
</main>
</div>
)
}
export default Landing

和Login组件

import { useNavigate } from 'solid-app-router'
import { Component, createSignal } from 'solid-js'
import Response from '../../models/response'
import { PostSession, Session } from '../../models/session'
import * as session from '../../services/session'
const Login: Component = () => {
const [email, setEmail] = createSignal('')
const [password, setPassword] = createSignal('')
const login = async (event: any) => {
event.preventDefault()
try {
console.log(`Login: ${email()}, Password: ${password()}`)
const res = await session.login({
email: email(),
password: password(),
} as PostSession)
if (res.status !== 200) {
window.alert('Login failed')
} else {
const navigate = useNavigate()
navigate('/dashboard', { replace: true })
}
} catch (error) {
console.error(error)
}
}
return (
<form>
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-floating">
<input
type="email"
class="form-control"
id="floatingInput"
placeholder="name@example.com"
value={email()}
onChange={(e: any) => setEmail(e.target.value)}
/>
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input
type="password"
class="form-control"
id="floatingPassword"
placeholder="Password"
value={password()}
onChange={(e: any) => setPassword(e.target.value)}
/>
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" /> Remember me
</label>
</div>
<button
class="w-100 btn btn-lg btn-primary"
onClick={e => login(e)}>
Sign in
</button>
</form>
)
}
export default Login

为我的用例设置路由器的正确方法是什么?

这里的问题(我认为)是您在事件处理程序中使用useNavigate()。该函数需要在树的呈现过程中同步调用,而不是在回调中调用,因为回调没有相同的执行上下文。试试这个:

const [email, setEmail] = createSignal('')
const [password, setPassword] = createSignal('')
const navigate = useNavigate()

,然后在您的事件处理程序中使用它,如:

} else {
navigate('/dashboard', { replace: true })
}

可以吗?

相关内容

最新更新