solid-js

Solid JS Query: Conditional Rendering on Routes using @solidjs.router


I'm new to Solid Js and currently creating an application with it. I'm lost on how to properly do a conditional render on my routes. Specifically, activating and deactivating routes on user logged in status

My current router set up is this:

export const App =  () => {
    const [authAccount] = useAuth()
    const {user, token} = authAccount.auth

 
    return (
        <>
            <Router>
                <Route path="/" component={user ? HomeScreen : LoginScreen}  />
                <Route path="/inventory" component={user ? InventoryScreen : LoginScreen} />
                <Route path="/transaction" component={user ? TransactionScreen : LoginScreen} />
                <Route path="/settings/" component={user ? AccountSettingsScreen : LoginScreen} />
                <Route path="/settings/notifications" component={user ? NotificationSettingsScreen : LoginScreen}/>
                <Route path="/settings/password" component={user ? PasswordSettingsScreen : LoginScreen} />
                <Route path="/ran" component={user ? RemindersAndNotificationScreen : LoginScreen} />
                <Route path="/inventory/:itemID" component={user ? ViewItemScreen : LoginScreen}/>
                <Route path="/inventory/add" component={user ? AddItemScreen : LoginScreen} />
                <Route path="/inventory/edit/:itemID" component={user ? EditItemScreen : LoginScreen}/>
                <Route path="/transaction/:transactionID" component={user ? ViewTransactionScreen : LoginScreen}/>
                <Route path="/transaction/edit/:transactionID" component={user ? EditTransactionScreen : LoginScreen}/>
                <Route path="/transaction/add/in/:itemID?" component={user ? TransactionInScreen : LoginScreen} />
                <Route path="/transaction/add/out/:itemID?" component={user ? TransactionOutScreen : LoginScreen} />
                <Route path="/transaction/add/lent/:itemID?" component={user ? TransactionLentScreen : LoginScreen} />
                <Route path="/transaction/add/return/:itemID?" component={user ? TransactionReturnScreen : LoginScreen} />
                
                <Route path="/login" component={!user ? LoginScreen : HomeScreen} />
                <Route path="/register" component={!user ? RegistrationScreen : HomeScreen} />
                <Route path="/fp" component={!user ? ForgotPasswordScreen : HomeScreen} />
            </Router>
        </>
    )
};

This results in my screens not properly rendering and I'm just lost on how do I do this.

Any help and suggestions is very appreciated.


Solution

  • It is best to run the evaluation before rendering the component.

    There are different ways to achieve conditional rendering based on validation. The most common ones are redirect and action.

    Redirect

    const getUser = cache(() => {
      const user = await api.getCurrentUser()
      if (!user) throw redirect("/login");
      return user;
    })
    

    https://github.com/solidjs/solid-router?tab=readme-ov-file#redirectpath-options

    Action

    import { action, revalidate, redirect } from "@solidjs/router"
    
    // anywhere
    const myAction = action(async (data) => {
      await doMutation(data);
      // throw a response to do a redirect
      throw redirect("/", { revalidate: getUser.keyFor(data.id) });
    });
    
    // in component
    <form action={myAction} method="post" />
    
    //or
    <button type="submit" formaction={myAction}></button>
    

    https://github.com/solidjs/solid-router?tab=readme-ov-file#action

    The examples are from the library itself, which you can check at: https://github.com/solidjs/solid-router