尽管我的应用程序被包装在路由标签中,但当我使用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
)

应用程序.tsx

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

登录组件的父级登录组件

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

以及登录组件

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 })
        }

这样行吗?

Typescript相关问答推荐

在React中实现具有独立页面的嵌套路径的最佳实践是什么?

类型脚本接口索引签名

当我点击外部按钮时,如何打开Html Select 选项菜单?

迁移到Reaction路由V6时,获取模块Reaction-Router-Dom';没有导出的成员RouteComponentProps错误

更新为Angular 17后的可选链运算符&?&问题

如何在TypeScrip中使用嵌套对象中的类型映射?

当方法参数和返回类型不相互扩展时如何从类型脚本中的子类推断类型

TypeScrip表示该类型不可赋值

打字类型保护递归判断

为什么不能使用$EVENT接收字符串数组?

如何使用Geojson模块和@Types/Geojson类型解析TypeScrip中的GeoJSON?

是否将自动导入样式从`~/目录/文件`改为`@/目录/文件`?

FatalError:Error TS6046:';--模块分辨率';选项的参数必须是:'; node ';,'; node 16';,'; node

如何以Angular 导入其他组件S配置文件

ANGLE订阅要么不更新价值,要么不识别价值变化

为什么发送空字段?

从类型脚本中元组的尾部获取第n个类型

如何从上传文件中删除预览文件图标?

是否使用类型将方法动态添加到类?

通过函数将对象文字类型映射到另一种类型的方法或解决方法