Маршрутизатор SolidJS useNavigate() выдает: Ошибка: убедитесь, что ваше приложение заключено в <Router />

Несмотря на то, что мое приложение заключено в тег Router, когда я использую useNavigate() или элемент <Navigate />, я получаю ту же ошибку login.tsx:27 Error: Make sure your app is wrapped in a <Router />

Вот мой index.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

и компонент входа

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.info(`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 = "[email protected]"
                    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

Как правильно настроить маршрутизатор для моего варианта использования?

Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
2
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема здесь (я думаю) в том, что вы используете useNavigate() в обработчике событий. Функцию необходимо вызывать синхронно во время рендеринга «внутри дерева», а не в обратном вызове, который не имеет того же контекста выполнения. Попробуй это:

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

а затем используйте его в своем обработчике событий, как и раньше:

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

Это работает?

Да, это так! Хороший улов!

Ray Kochenderfer 04.05.2022 14:30

Другие вопросы по теме