I'm just simply sick of all the ternary expressions and logical operators, so I ported some common control flows from SolidJS.
Create pull requests if you find any issues or have suggestions to improve the library.
npm install react-ctrlflow
# or
yarn add react-ctrlflow
# or
pnpm add react-ctrlflow
# or
bun add react-ctrlflow
import { For } from 'react-ctrlflow';
type ForProps<T extends readonly unknown[], U extends ReactElement> = {
each: T | undefined | null | false;
fallback?: ReactElement;
getKey?: (item: T[number], index: number) => string | number;
children: (item: T[number], index: number) => U;
};
function For<T extends readonly unknown[], U extends ReactElement>({ each, fallback, getKey, children }: ForProps<T, U>): ReactNode;
An easy way to iterate over a list of items.
The callback takes the current item as the first argument:
<For each={state.list} fallback={<div>Loading...</div>}>
{(item) => <div>{item}</div>}
</For>
The optional second argument is an index signal:
<For each={state.list} fallback={<div>Loading...</div>}>
{(item, index) => <div>#{index} {item}</div>}
</For>
type ShowProps<T> = {
when: NonNullable<T> | undefined | null | false;
keyed?: boolean;
fallback?: ReactNode;
children: ReactNode | ((item: T) => ReactNode);
};
function Show<T>({ when, keyed = false, fallback, children }: ShowProps<T>): ReactNode;
The Show control flow is used to conditional render part of the view: it renders children
when the when
is truthy, an fallback
otherwise. It is similar to the ternary operator (when ? children : fallback
) but is ideal for templating JSX.
<Show when={state.count > 0} fallback={<div>Loading...</div>}>
<div>My Content</div>
</Show>
Show can also be used as a way of keying blocks to a specific data model. Ex the function is re-executed whenever the user model is replaced.
<Show when={state.user} fallback={<div>Loading...</div>} keyed>
{(user) => <div>{user.firstName}</div>}
</Show>
Used to match multiple conditions and render the first matching component. This will return the first matching component.
import { Switch, Match } from 'react-ctrlflow';
type MatchProps<T> = {
when: T | undefined | null | false;
keyed?: boolean;
children: ReactNode | ((item: T) => ReactNode);
};
function Switch({ fallback, children }: { fallback?: ReactNode; children: ReactNode; }): ReactNode;
function Match<T>({ when, keyed = false, children, __ignoreContext = false }: MatchProps<T> & { __ignoreContext?: boolean }): ReactNode | null
Useful for when there are more than 2 mutual exclusive conditions. For example, it can be used to perform basic routing:
<Switch fallback={<div>Not Found</div>}>
<Match when={state.route === "home"}>
<Home />
</Match>
<Match when={state.route === "settings"}>
<Settings />
</Match>
</Switch>
Match also supports function children to serve as keyed flow.
This library aims to allow React developers to use a declarative control flow syntax similar to SolidJS, but please note:
- There are fundamental differences between the reactive models of React and SolidJS.
- These components are wrappers for React and will not provide the performance advantages of SolidJS.
- Some behaviors may be slightly different because they are implemented in React.