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