alternative tangled frontend (extremely wip)
at main 297 lines 8.3 kB view raw view rendered
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).