alternative tangled frontend (extremely wip)
1Welcome to your new TanStack app!
2
3# Getting Started
4
5To run this application:
6
7```bash
8pnpm install
9pnpm start
10```
11
12# Building For Production
13
14To build this application for production:
15
16```bash
17pnpm build
18```
19
20## Testing
21
22This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with:
23
24```bash
25pnpm test
26```
27
28## Styling
29
30This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
31
32## Linting & Formatting
33
34This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available:
35
36```bash
37pnpm lint
38pnpm format
39pnpm check
40```
41
42## Routing
43
44This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`.
45
46### Adding A Route
47
48To add a new route to your application just add another a new file in the `./src/routes` directory.
49
50TanStack will automatically generate the content of the route file for you.
51
52Now that you have two routes you can use a `Link` component to navigate between them.
53
54### Adding Links
55
56To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.
57
58```tsx
59import { Link } from "@tanstack/react-router";
60```
61
62Then anywhere in your JSX you can use it like so:
63
64```tsx
65<Link to="/about">About</Link>
66```
67
68This will create a link that will navigate to the `/about` route.
69
70More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
71
72### Using A Layout
73
74In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `<Outlet />` component.
75
76Here is an example layout that includes a header:
77
78```tsx
79import { Outlet, createRootRoute } from "@tanstack/react-router";
80import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
81
82import { Link } from "@tanstack/react-router";
83
84export const Route = createRootRoute({
85 component: () => (
86 <>
87 <header>
88 <nav>
89 <Link to="/">Home</Link>
90 <Link to="/about">About</Link>
91 </nav>
92 </header>
93 <Outlet />
94 <TanStackRouterDevtools />
95 </>
96 ),
97});
98```
99
100The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.
101
102More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).
103
104## Data Fetching
105
106There are multiple ways to fetch data in your application. You can use TanStack Query to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered.
107
108For example:
109
110```tsx
111const peopleRoute = createRoute({
112 getParentRoute: () => rootRoute,
113 path: "/people",
114 loader: async () => {
115 const response = await fetch("https://swapi.dev/api/people");
116 return response.json() as Promise<{
117 results: {
118 name: string;
119 }[];
120 }>;
121 },
122 component: () => {
123 const data = peopleRoute.useLoaderData();
124 return (
125 <ul>
126 {data.results.map((person) => (
127 <li key={person.name}>{person.name}</li>
128 ))}
129 </ul>
130 );
131 },
132});
133```
134
135Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).
136
137### React-Query
138
139React-Query is an excellent addition or alternative to route loading and integrating it into you application is a breeze.
140
141First add your dependencies:
142
143```bash
144pnpm add @tanstack/react-query @tanstack/react-query-devtools
145```
146
147Next we'll need to create a query client and provider. We recommend putting those in `main.tsx`.
148
149```tsx
150import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
151
152// ...
153
154const queryClient = new QueryClient();
155
156// ...
157
158if (!rootElement.innerHTML) {
159 const root = ReactDOM.createRoot(rootElement);
160
161 root.render(
162 <QueryClientProvider client={queryClient}>
163 <RouterProvider router={router} />
164 </QueryClientProvider>,
165 );
166}
167```
168
169You can also add TanStack Query Devtools to the root route (optional).
170
171```tsx
172import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
173
174const rootRoute = createRootRoute({
175 component: () => (
176 <>
177 <Outlet />
178 <ReactQueryDevtools buttonPosition="top-right" />
179 <TanStackRouterDevtools />
180 </>
181 ),
182});
183```
184
185Now you can use `useQuery` to fetch your data.
186
187```tsx
188import { useQuery } from "@tanstack/react-query";
189
190import "./App.css";
191
192function App() {
193 const { data } = useQuery({
194 queryKey: ["people"],
195 queryFn: () =>
196 fetch("https://swapi.dev/api/people")
197 .then((res) => res.json())
198 .then((data) => data.results as { name: string }[]),
199 initialData: [],
200 });
201
202 return (
203 <div>
204 <ul>
205 {data.map((person) => (
206 <li key={person.name}>{person.name}</li>
207 ))}
208 </ul>
209 </div>
210 );
211}
212
213export default App;
214```
215
216You can find out everything you need to know on how to use React-Query in the [React-Query documentation](https://tanstack.com/query/latest/docs/framework/react/overview).
217
218## State Management
219
220Another common requirement for React applications is state management. There are many options for state management in React. TanStack Store provides a great starting point for your project.
221
222First you need to add TanStack Store as a dependency:
223
224```bash
225pnpm add @tanstack/store
226```
227
228Now let's create a simple counter in the `src/App.tsx` file as a demonstration.
229
230```tsx
231import { useStore } from "@tanstack/react-store";
232import { Store } from "@tanstack/store";
233import "./App.css";
234
235const countStore = new Store(0);
236
237function App() {
238 const count = useStore(countStore);
239 return (
240 <div>
241 <button onClick={() => countStore.setState((n) => n + 1)}>
242 Increment - {count}
243 </button>
244 </div>
245 );
246}
247
248export default App;
249```
250
251One of the many nice features of TanStack Store is the ability to derive state from other state. That derived state will update when the base state updates.
252
253Let's check this out by doubling the count using derived state.
254
255```tsx
256import { useStore } from "@tanstack/react-store";
257import { Store, Derived } from "@tanstack/store";
258import "./App.css";
259
260const countStore = new Store(0);
261
262const doubledStore = new Derived({
263 fn: () => countStore.state * 2,
264 deps: [countStore],
265});
266doubledStore.mount();
267
268function App() {
269 const count = useStore(countStore);
270 const doubledCount = useStore(doubledStore);
271
272 return (
273 <div>
274 <button onClick={() => countStore.setState((n) => n + 1)}>
275 Increment - {count}
276 </button>
277 <div>Doubled - {doubledCount}</div>
278 </div>
279 );
280}
281
282export default App;
283```
284
285We use the `Derived` class to create a new store that is derived from another store. The `Derived` class has a `mount` method that will start the derived store updating.
286
287Once we've created the derived store we can use it in the `App` component just like we would any other store using the `useStore` hook.
288
289You can find out everything you need to know on how to use TanStack Store in the [TanStack Store documentation](https://tanstack.com/store/latest).
290
291# Demo files
292
293Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed.
294
295# Learn More
296
297You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).