Skip to content

Commit b898a0d

Browse files
committed
update docs
1 parent 9f57a2b commit b898a0d

9 files changed

+57
-58
lines changed

docs/additional-resources.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
- [Official Documentation](https://react.dev/)
66
- [Tao Of React](https://alexkondov.com/tao-of-react/)
7-
- [React Handbook](https://github.com/ericdiviney/react-handbook/)
7+
- [React Handbook](https://reacthandbook.dev/)
88
- [React Philosophies](https://github.com/mithi/react-philosophies)
99
- [React Patterns](https://reactpatterns.com/)
10+
- [React Typescript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/)
1011

1112
## JavaScript
1213

@@ -20,4 +21,3 @@
2021
- [patterns.dev](https://www.patterns.dev/)
2122
- [Naming Cheatsheet](https://github.com/kettanaito/naming-cheatsheet)
2223
- [Clean Code Javascript](https://github.com/ryanmcdermott/clean-code-javascript)
23-
- [React Typescript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/)

docs/api-layer.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
When your application interacts with either RESTful or GraphQL APIs, it is beneficial to use a single instance of the API client that has been pre-configured and can be reused throughout the application. For example, you can create a single API client instance using the native fetch API or libraries such as [axios](https://github.com/axios/axios), [graphql-request](https://github.com/prisma-labs/graphql-request), or [apollo-client](https://www.apollographql.com/docs/react/) with predefined configuration settings.
66

7-
[Example Code for API Client](../src/lib/api-client.ts)
7+
[API Client Example Code](../src/lib/api-client.ts)
88

99
### Define and Export Request Declarations
1010

@@ -15,9 +15,9 @@ Every API request declaration should consist of:
1515

1616
- Types and validation schemas for the request and response data
1717
- A fetcher function that calls an endpoint, using the API client instance
18-
- A hook that consumes the fetcher function that is built on top of libraries such as [react-query](https://react-query.tanstack.com/), [swr](<[https://](https://swr.vercel.app/)>), [apollo-client](https://www.apollographql.com/docs/react/), [urql](https://formidable.com/open-source/urql/), etc. to manage the data fetching and caching logic.
18+
- A hook that consumes the fetcher function that is built on top of libraries such as [react-query](https://tanstack.com/query), [swr](<[https://](https://swr.vercel.app/)>), [apollo-client](https://www.apollographql.com/docs/react/), [urql](https://formidable.com/open-source/urql/), etc. to manage the data fetching and caching logic.
1919

2020
This approach simplifies the tracking of defined endpoints available in the application. Additionally, typing the responses and inferring them further down the application enhances application type safety.
2121

22-
[Example Code for API Request Declarations - Query](../src/features/discussions/api/get-discussions.ts)
23-
[Example Code for API Request Declarations - Mutation](../src/features/discussions/api/create-discussion.ts)
22+
[API Request Declarations - Query - Example Code](../src/features/discussions/api/get-discussions.ts)
23+
[API Request Declarations - Mutation - Example Code](../src/features/discussions/api/create-discussion.ts)

docs/error-handling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
### API Errors
44

5-
Set up an interceptor for handling errors. You can use it to fire a notification toast to notify users that something went wrong, log out unauthorized users, or send new requests for refreshing tokens.
5+
Implement an interceptor to manage errors effectively. This interceptor can be utilized to trigger notification toasts informing users of errors, log out unauthorized users, or send requests to refresh tokens to maintain secure and seamless application operation.
66

77
[API Errors Notification Example Code](../src/lib/api-client.ts)
88

99
### In App Errors
1010

11-
Use error boundaries to handle errors that happen in the React tree. It is very popular to set only 1 single error boundary for the entire application, which would break the entire application when an error occurs. That's why you should have more error boundaries on more specific parts of the application. That way if an error occurs the app will still work without the need to restart it.
11+
Utilize error boundaries in React to handle errors within specific parts of your application. Instead of having only one error boundary for the entire app, consider placing multiple error boundaries in different areas. This way, if an error occurs, it can be contained and managed locally without disrupting the entire application's functionality, ensuring a smoother user experience.
1212

1313
[Error Boundary Example Code](../src/providers/app.tsx)
1414

docs/performance.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
### Code Splitting
44

5-
Code splitting is a technique of splitting production JavaScript into smaller files, thus allowing the application to be only partially downloaded. Any unused code will not be downloaded until it is required by the application.
5+
Code splitting involves dividing production JavaScript into smaller files to optimize application loading times. This technique enables the application to be downloaded in parts, fetching only the necessary code when required.
66

7-
Most of the time code splitting should be done on the routes level, but can also be used for other lazy loaded parts of application.
8-
9-
Do not code split everything as it might even worsen your application's performance because of many requests your application needs to make to get all the chunks.
7+
Ideally, code splitting should be implemented at the routes level, ensuring that only essential code is loaded initially, with additional parts fetched lazily as needed. It's important to avoid excessive code splitting, as this can lead to a performance decline due to the increased number of requests required to fetch all the code chunks. Strategic code splitting, focusing on critical parts of the application, helps balance performance optimization with efficient resource loading.
108

119
[Code Splitting Example Code](../src/routes/index.tsx)
1210

@@ -28,7 +26,7 @@ const [state, setState] = React.useState(() => myExpensiveFn());
2826

2927
- If you develop an application that requires a state to track many elements at once, you might consider state management libraries with atomic updates such as [jotai](https://jotai.pmnd.rs/).
3028

31-
- Use React Context wisely. React Context is good for low-velocity data like themes, user data, small local state etc. While dealing with medium-velocity/high-velocity data, you may consider using the [use-context-selector](https://github.com/dai-shi/use-context-selector) library that supports selectors (selectors are already built-in in most popular state management libraries like [zustand](https://docs.pmnd.rs/zustand/getting-started/introduction) or [jotai](https://jotai.org/)). Important to remember, context is often used as the "golden tool" for props drilling, whereas in many scenarios you may satisfy your needs by [lifting the state up](https://react.dev/learn/sharing-state-between-components#lifting-state-up-by-example) or [a proper composition of components](https://react.dev/learn/passing-data-deeply-with-context#before-you-use-context). Do not rush with context.
29+
- Use React Context wisely. React Context is good for low-velocity data like themes, user data, small local state etc. While dealing with medium-velocity/high-velocity data, you may consider using the [use-context-selector](https://github.com/dai-shi/use-context-selector) library that supports selectors (selectors are already built-in in most popular state management libraries like [zustand](https://docs.pmnd.rs/zustand/getting-started/introduction) or [jotai](https://jotai.org/)). Important to remember, context is often used as the "golden tool" for props drilling, whereas in many scenarios you may satisfy your needs by [lifting the state up](https://react.dev/learn/sharing-state-between-components#lifting-state-up-by-example) or [a proper composition of components](https://react.dev/learn/passing-data-deeply-with-context#before-you-use-context). Do not rush with context and global state.
3230

3331
- If your application is expected to have frequent updates that might affect performance, consider switching from runtime styling solutions such as [emotion](https://emotion.sh/docs/introduction), [styled-components](https://styled-components.com/) that generate styles during runtime) to zero runtime styling solutions ([tailwind](https://tailwindcss.com/), [vanilla-extract](https://github.com/seek-oss/vanilla-extract), [CSS modules](https://github.com/css-modules/css-modules) which generate styles during build time).
3432

docs/project-configuration.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
# ⚙️ Project Configuration
22

3-
The application has been bootstrapped using `Vite ` and its `react-ts` template. It allows us to create applications quickly without dealing with a complex tooling setup such as bundling, transpiling etc.
3+
The sample application has been bootstrapped using `Vite ` and its `react-ts` template. It allows us to create applications quickly without dealing with a complex tooling setup such as bundling, transpiling etc.
44

5-
Other popular ways we could have bootstrapped the application are:
5+
Other popular ways you can bootstrap the application are:
66

77
- [Next.js](https://nextjs.org/)
88
- [Remix](https://remix.run/)
99

10-
But for simplicity we will use Vite, as it doesn't force us to use the meta-framework specific things, and allows us to focus on React.
10+
For simplicity we will use Vite, as it doesn't force us to use the meta-framework specific things, and allows us to focus on React.
1111

1212
You should always configure and use the following tools:
1313

1414
#### ESLint
1515

16-
ESLint is a linting tool for JavaScript. By providing specific configuration defined in the`.eslintrc.js` file it prevents developers from making silly mistakes in their code and enforces consistency in the codebase.
16+
ESLint serves as a valuable linting tool for JavaScript, helping developers in maintaining code quality and adhering to coding standards. By configuring rules in the `.eslintrc.js` file, ESLint helps identify and prevent common errors, ensuring code correctness and promoting consistency throughout the codebase. This approach not only helps in catching mistakes early but also enforces uniformity in coding practices, thereby enhancing the overall quality and readability of the code.
1717

1818
[ESLint Configuration Example Code](../.eslintrc.js)
1919

2020
#### Prettier
2121

22-
Prettier is a great tool for formatting code. It enforces a consistent code style across your entire codebase. By utilizing the "format on save" feature in your IDE you can automatically format the code based on the configuration provided in the `.prettierrc` file. It will also give you good feedback when something is wrong with the code. If the auto-format doesn't work, something is wrong with the code.
22+
Prettier is a useful tool for maintaining consistent code formatting in your project. By enabling the "format on save" feature in your IDE, code is automatically formatted according to the rules set in the `.prettierrc` configuration file. This practice ensures a uniform code style across your codebase and provides helpful feedback on code issues. If the auto-formatting fails, it signals potential syntax error. Furthermore, Prettier can be integrated with ESLint to handle code formatting tasks alongside enforcing coding standards effectively throughout the development process.
2323

2424
[Prettier Configuration Example Code](../.prettierrc)
2525

2626
#### TypeScript
2727

28-
ESLint is great for catching some of the bugs related to the language, but since JavaScript is a dynamic language ESLint cannot check data that run through the applications, which can lead to bugs, especially on larger projects. That is why TypeScript should be used. It is very useful during large refactors because it reports any issues you might miss otherwise. When refactoring, change the type declaration first, then fix all the TypeScript errors throughout the project and you are done. One thing you should keep in mind is that TypeScript does not protect your application from failing during runtime, it only does type checking during build time, but it increases development confidence drastically anyways. Here is a [great resource on using TypeScript with React](https://react-typescript-cheatsheet.netlify.app/).
28+
ESLint is effective for detecting language-related bugs in JavaScript. However, due to JavaScript's dynamic nature, ESLint may not catch all runtime data issues, especially in complex projects. To address this, TypeScript is recommended. TypeScript is valuable for identifying issues during large refactoring processes that may go unnoticed. When refactoring, prioritize updating type declarations first, then resolving TypeScript errors throughout the project. It's important to note that while TypeScript enhances development confidence by performing type checking at build time, it does not prevent runtime failures. Here is a [great resource on using TypeScript with React](https://react-typescript-cheatsheet.netlify.app/).
2929

3030
#### Husky
3131

32-
Husky is a tool for executing git hooks. Use Husky to run your code validations before every commit, thus making sure the code is in the best shape possible at any point of time and no faulty commits get into the repo. It can run linting, code formatting and type checking, etc. before it allows pushing the code. You can check how to configure it [here](https://typicode.github.io/husky/#/?id=usage).
32+
Husky is a valuable tool for implementing and executing git hooks in your workflow. By utilizing Husky to run code validations before each commit, you can ensure that your code maintains high standards and that no faulty commits are pushed to the repository. Husky enables you to perform various tasks such as linting, code formatting, and type checking before allowing code pushes. You can check how to configure it [here](https://typicode.github.io/husky/#/?id=usage).
3333

3434
#### Absolute imports
3535

docs/project-structure.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 🗄️ Project Structure
22

3-
Most of the code lives in the `src` folder and looks like this:
3+
Most of the code lives in the `src` folder and looks something like this:
44

55
```sh
66
src
@@ -15,22 +15,22 @@ src
1515
|
1616
+-- hooks # shared hooks used across the entire application
1717
|
18-
+-- lib # re-exporting different libraries preconfigured for the application
18+
+-- lib # reusable libraries preconfigured for the application
1919
|
2020
+-- providers # all of the application providers
2121
|
2222
+-- routes # routes configuration
2323
|
2424
+-- stores # global state stores
2525
|
26-
+-- test # test utilities and mock server
26+
+-- test # test utilities and mocks
2727
|
28-
+-- types # base types used across the application
28+
+-- types # shared types used across the application
2929
|
3030
+-- utils # shared utility functions
3131
```
3232

33-
In order to scale the application in the easiest and most maintainable way, keep most of the code inside the `features` folder, which should contain different feature-based things. Every `feature` folder should contain domain specific code for a given feature. This will allow you to keep functionalities scoped to a feature and not mix its declarations with shared things. This is much easier to maintain than a flat folder structure with many files.
33+
For easy scalability and maintenance, organize most of the code within the features folder. Each feature folder should contain code specific to that feature, keeping things neatly separated. This approach helps prevent mixing feature-related code with shared components, making it simpler to manage and maintain the codebase compared to having many files in a flat folder structure. By adopting this method, you can enhance collaboration, readability, and scalability in the application's architecture.
3434

3535
A feature could have the following structure:
3636

@@ -92,7 +92,7 @@ To prevent circular dependencies, here is another ESLint rule that can be used:
9292
}
9393
```
9494
95-
This was inspired by how [NX](https://nx.dev/) handles libraries that are isolated but available to be used by the other modules. Think of a feature as a library or a module that is self-contained but can expose different parts to other features via its entry point. This approach will also make it easier to split the application in a monorepo in the future.
95+
This was inspired by how [NX](https://nx.dev/) handles libraries that are isolated but available to be used by the other modules. Think of a feature as a library or a module that is self-contained but can expose different parts to other features via its entry point. This approach would also make it easier to split the application in a monorepo in the future.
9696
9797
This way, you can ensure that the codebase is clean and easy to maintain.
9898

0 commit comments

Comments
 (0)