Conditional UI Display

Conditional User Interface Display

In dynamic front-end applications, we typically want to show different user interfaces when the application is in different states. An example of this is displaying a welcome message to either a guest or an authenticated user.

For a guest, we might want to display a generic welcome message alongside a sign-in form:

tsx
<div>Welcome to the application. Please sign in to continue.</div>
<SignInForm />
tsx
<div>Welcome to the application. Please sign in to continue.</div>
<SignInForm />

For an authenticated user, we might want to greet them by their name and provide them with their custom dashboard:

tsx
<div>Welcome back, Jessica!</div>
<Dashboard />
tsx
<div>Welcome back, Jessica!</div>
<Dashboard />

Conditionally showing content

In Solid, we can use the <Show /> component to conditionally show content. The <Show /> component takes a when prop and an optional fallback prop.

  • When the when prop is true, the JSX inside <Show /> is displayed
  • When the when prop is false, the JSX inside fallback is displayed (if provided)

The following example shows how we would use the <Show /> component to conditionally display a sign-in or dashboard page:

tsx
import { Show } from "solid-js";
function Home(props) {
return (
<Show
when={props.isLoggedin}
fallback={
<>
<div>Welcome to the application. Please sign in to continue.</div>
<SignInForm />
</>
}
>
<div>Welcome back, {props.firstName}!</div>
<Dashboard />
</Show>
);
}
tsx
import { Show } from "solid-js";
function Home(props) {
return (
<Show
when={props.isLoggedin}
fallback={
<>
<div>Welcome to the application. Please sign in to continue.</div>
<SignInForm />
</>
}
>
<div>Welcome back, {props.firstName}!</div>
<Dashboard />
</Show>
);
}

When props.isLoggedIn is true, we welcome the user back and show the <Dashboard />. When props.isLoggedIn is false, we display the fallback content, which is our generic greeting message and the <SignInForm />.

Iterating over data with <For />

User interfaces often require us to display lists of data. These lists can typically be of any length, and therefore we can't just hardcode each element. Instead, Solid gives us the <For /> component. If you have been coding along with the Bookshelf app example, you'll notice we already had to use this component.

The <For /> component takes the array you want to loop over in the each prop:

jsx
const books = ["Book 1", "Book 2"];
<For each={books}>...</For>;
jsx
const books = ["Book 1", "Book 2"];
<For each={books}>...</For>;

Inside the <For /> component, you use a callback function to loop over the items. In this case, we create a new list item <li> for each book in our books array:

jsx
const books = ["Book 1", "Book 2"];
<For each={books}>
{(book) => {
return <li>{book}</li>;
}}
</For>;
jsx
const books = ["Book 1", "Book 2"];
<For each={books}>
{(book) => {
return <li>{book}</li>;
}}
</For>;

Revisiting the bookshelf

In the Adding Interactivity with State section of this tutorial, we found ourselves already needing the <For /> component. This allowed us to iterate over any number of books in on our bookshelf:

tsx
import { For } from "solid-js";
export function BookList(props) {
const totalBooks = () => props.books.length;
return (
<>
<h2>My books ({totalBooks()})</h2>
<ul>
<For each={props.books}>
{(book) => {
return (
<li>
{book.title}
<span style={{ "font-style": "italic" }}> ({book.author})</span>
</li>
);
}}
</For>
</ul>
</>
);
}
tsx
import { For } from "solid-js";
export function BookList(props) {
const totalBooks = () => props.books.length;
return (
<>
<h2>My books ({totalBooks()})</h2>
<ul>
<For each={props.books}>
{(book) => {
return (
<li>
{book.title}
<span style={{ "font-style": "italic" }}> ({book.author})</span>
</li>
);
}}
</For>
</ul>
</>
);
}

Let's now use the <Show /> component. We will only show our AddBook form if the user wants to add a book.

We will create a boolean signal in the Bookshelf component that tracks whether or not the form is open and add buttons to open and close the form. We will use the <Show /> component to conditionally display the form.

tsx
import { createSignal, Show } from "solid-js";
import { BookList } from "./BookList";
import { AddBook } from "./AddBook";
const initialBooks = [
{ title: "Code Complete", author: "Steve McConnell" },
{ title: "The Hobbit", author: "J.R.R. Tolkien" },
{ title: "Living a Feminist Life", author: "Sarah Ahmed" },
];
function Bookshelf(props) {
const [books, setBooks] = createSignal(initialBooks);
const [showForm, setShowForm] = createSignal(false);
const toggleForm = () => setShowForm(!showForm());
return (
<div>
<h1>{props.name}'s Bookshelf</h1>
<BookList books={books()} />
<Show
when={showForm()}
fallback={<button onClick={toggleForm}>Add a book</button>}
>
<AddBook setBooks={setBooks} />
<button onClick={toggleForm}>Finished adding books</button>
</Show>
</div>
);
}
function App() {
return (
<Bookshelf name="Solid"/>
);
}
export default App;
tsx
import { createSignal, Show } from "solid-js";
import { BookList } from "./BookList";
import { AddBook } from "./AddBook";
const initialBooks = [
{ title: "Code Complete", author: "Steve McConnell" },
{ title: "The Hobbit", author: "J.R.R. Tolkien" },
{ title: "Living a Feminist Life", author: "Sarah Ahmed" },
];
function Bookshelf(props) {
const [books, setBooks] = createSignal(initialBooks);
const [showForm, setShowForm] = createSignal(false);
const toggleForm = () => setShowForm(!showForm());
return (
<div>
<h1>{props.name}'s Bookshelf</h1>
<BookList books={books()} />
<Show
when={showForm()}
fallback={<button onClick={toggleForm}>Add a book</button>}
>
<AddBook setBooks={setBooks} />
<button onClick={toggleForm}>Finished adding books</button>
</Show>
</div>
);
}
function App() {
return (
<Bookshelf name="Solid"/>
);
}
export default App;

When showForm() is true, the app displays the <AddBook /> form and a button that allows us to hide the form again. When showForm() is false, the fallback component is displayed—a button to show the <AddBook /> form.

Solid's Bookshelf

My books (2)

  • Code Complete (Steve McConnell)
  • The Hobbit (J.R.R. Tolkien)