Skip to content

Basic Usage with React

work in progress

Fetching sync and async dependencies from ITI in React is conceptually similar to data fetching. If you’ve used libraries like React Query, swr, Apollo Client or similar this will feel familiar.

./src/Profile.tsx
import useSWR from "swr"
function Profile() {
const { data, error } = useSWR("/api/user", fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
./src/Profile.tsx
import { useContainer } from "./_containers/main-app"
function Profile() {
const [auth, authErr] = useContainer().auth
if (authErr) return <div>failed to load</div>
if (!auth) return <div>loading...</div>
return <div>hello {auth.profile.name}!</div>
}

useContainerSet

./src/Profile.tsx
import { useContainer, useContainerSet } from "./_containers/main-app"
// Callback style
function Profile() {
const [profileDeps, profileDepsErr] = useContainerSet((c) => [c.auth, c.env])
if (!profileDeps || profileDepsErr) return null
const { auth, env } = profileDeps
return <div>hello {auth.profile.name}!</div>
}
// Literal style
function Profile() {
const [profileDeps, profileDepsErr] = useContainerSet(["auth", "env"])
if (!profileDeps || profileDepsErr) return null
const { auth, env } = profileDeps
return <div>hello {auth.profile.name}!</div>
}

You might want a simpler API for your components

So we could go

From:

const [profileDeps, profileDepsErr] = useContainerSet(["auth", "env"])
if (!profileDeps || profileDepsErr) return null

To:

const { auth, env } = useProfileDeps()

To achieve that we will have to create a wrapping component. Very similar to React.Suspense

// This component is loaded dynamically
const OtherComponent = React.lazy(() => import("./OtherComponent"))
function MyComponent() {
return (
// Displays <Spinner> until OtherComponent loads
<React.Suspense fallback={<Spinner />}>
<div>
<OtherComponent />
</div>
</React.Suspense>
)
}

We will create a wrapping component that will fetch dependencies, provide fallback and provide context for nested components

./src/_containers-react/EnsureEcommerce.tsx
import React, { useContext } from "react"
import { generateEnsureContainerSet } from "iti-react"
import { useContainerSet } from "./_editor-app-hooks"
const x = generateEnsureContainerSet(() =>
useContainerSet(["ecommerce", "auth"])
)
export const EnsureEcommerceContainer = x.EnsureWrapper
export const useEcommerceContext = x.contextHook
./src/App.tsx
import { EnsureEcommerceContainer } from "./_containers-react/EnsureEcommerce"
export const App = () => (
<div className="App">
<EnsureEcommerceContainer fallback={<>Loading</>}>
<MainApp />
</EnsureEcommerceContainer>
</div>
)
./src/Currency.tsx
import { useEcommerceContext } from "../../../../_containers-react/EnsureEcommerce"
export const CurrencyInfo = () => {
const { currencyStore, taxStore } = useEcommerceContext().ecommerce
return <div>{currencyStore.currency}</div>
}