Files and folders
The recommended folder structure of the application is to separate features from components. This enforces the idea that a feature is not tied to the UI, they can be implemented in isolation and used across UI components, no matter what page they are on.
pages/
index.tsx
/PageA
index.tsx
ComponentA.tsx
ComponentB.tsx
features/
FeatureA/
index.ts
Feature.tsx
Feature.test.tsx
environment/
index.tsx
EffectA/
test.ts
browser.ts
index.ts
Pages
pages/
index.tsx
/Project
index.tsx
Project.tsx
SideBar.tsx
Applications typically has navigation to different pages, where a page reflects a feature. The index.tsx of the pages folder would hold the router.
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { DashboardPage } from './dashboard'
import { ProjectPage } from './project'
export const Pages = () => (
<Router>
<Switch>
<Route exact path="/">
<DashboardPage />
</Route>
<Route path="/projects/:id">
<ProjectPage />
</Route>
</Switch>
</Router>
);
Each page has its own index.tsx file mapping any router params to the feature. This is an important separation to not make features dependent on a router.
Any children components of the feature now has access to the feature itself. You might compose a layout with multiple features in this file.
import { ProjectFeature } from '../features/Project'
import { Project } from './Project'
export const ProjectPage = () => {
const { id } = useParams<{ id: string; }>();
return (
<ProjectFeature id={id}>
<Project />
</ProjectFeature>
)
}
Features
features/
FeatureA/
index.ts
Feature.tsx
Feature.test.tsx
The application logic is expressed as provider components. Read more in features on how to define a feature. Any related utilities and tests is defined within the same folder.
Environment
environment/
index.tsx
EffectA/
test.ts
browser.ts
index.ts
This folder contains all the environment effects the application needs to operate. Each environment effect has its own folder where it defines how to operate in the different environments, typically test and browser.
The main index.tsx file contains the provider for exposing the environment to the features.
import { createEnvironment } from 'react-states'
import { EffectA } from './EffectA'
export interface Environment {
effectA: EffectA
}
const {
EnvironmentProvider,
useEnvironment
} = createEnvironment<Environment>()
export {
EnvironmentProvider,
useEnvironment
}
Providing the actual environment happens in the main file of the application. For example:
import { Environment, EnvironmentProvider } from '../environment'
import { createEffectA } from '../environment/effectA/browser'
const environment: Environment = {
effectA: createEffectA()
}
const App = () => {
return (
<EnvironmentProvider environment={environment}>
{/* The app components */}
</EnvironmentProvider>
)
}
Last updated
Was this helpful?