diff --git a/react/modules/forms/README.md b/react/modules/forms/README.md index 6e0578cdd..2febc6249 100644 --- a/react/modules/forms/README.md +++ b/react/modules/forms/README.md @@ -63,7 +63,8 @@ Students are encouraged to explore the following resources: - [article: How to perform form validation in React?](https://www.geeksforgeeks.org/how-to-perform-form-validation-in-react/) - [10 minutes] - [article: React form validation with React Hook Form and Yup](https://dev.to/franciscomendes10866/react-form-validation-with-react-hook-form-and-yup-4a98) - [20 minutes] - [article: Creating a React Form Using React Hook Form and Yup in TypeScript](https://medium.com/@msgold/creating-a-react-form-using-react-hook-form-and-yup-in-typescript-640168c5ed57) - [30 minutes] - - [Yup](https://github.com/jquense/yup?tab=readme-ov-file#yup) - [50 minutes] + - [Yup](https://github.com/jquense/yup?tab=readme-ov-file#yup) - [25 minutes] + - [Zod](https://github.com/colinhacks/zod) - [30 minutes] 8. **How to handle file uploads in React forms:** diff --git a/react/modules/performance/README.md b/react/modules/performance/README.md new file mode 100644 index 000000000..6deae32fc --- /dev/null +++ b/react/modules/performance/README.md @@ -0,0 +1,30 @@ +# [React](https://github.com/rolling-scopes-school/tasks/tree/master/react) Performance 🌟 + +## Module Overview 📚 + +The "React Performance" module delves into techniques and best practices to optimize the performance of React applications. Students will gain insights into various strategies to enhance the speed and efficiency of their React projects. The module covers topics such as code splitting, lazy loading, memoization, and the use of performance monitoring tools to identify and address bottlenecks. + +## Learning Objectives 🎯 + +Students will: + +- Understand the importance of performance optimization in React applications. +- Learn how to use React's **memoization** techniques to prevent unnecessary re-renders. +- Know how to effectively use **React keys** to optimize list rendering. +- Understand the use of **React's useCallback** hook to memoize callback functions. +- Understand how to use **React.memo** to optimize functional components. +- Learn how to use **React's Profiler** to identify performance bottlenecks. +- Learn about **code splitting** and **lazy loading** to improve application load times. +- Understand the impact of **reconciliation** and how to optimize it. +- Learn about **virtualization** techniques to efficiently render large lists. +- Know how to use performance monitoring tools to track and improve application performance. + +## Approximate Module Completion Time ⏱️ + +- **7 hours** + +## Theory 📖 + +Students are encouraged to explore the following resources: + +1. **useCallback, useMemo, React.memo** diff --git a/react/modules/tasks/class-components.md b/react/modules/tasks/class-components.md index b11132703..11ac0101d 100644 --- a/react/modules/tasks/class-components.md +++ b/react/modules/tasks/class-components.md @@ -62,110 +62,14 @@ Non-successful response. ## Technical Requirements 1. Create a separate branch for this task. Branch name: "class-components". -2. Language Requirement - - Use **TypeScript** for the project. -3. Project Setup - - - Initialize the project using [Vite](https://vitejs.dev/guide/) with the [_react-ts_ template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts). - ```sh - # npm 7+, extra double-dash is needed: - npm create vite@latest rs-react-app -- --template react-ts - ``` - -4. Code Quality Tools - - 1. ESLint - - ESlint v.9 is already a part of the _react-ts_ setup. - 2. Prettier - - - Integrate Prettier for code formatting. - You can execute the following command to add missing plugins: - - ```sh - npm install -D eslint-plugin-react eslint-plugin-prettier eslint-config-prettier eslint-plugin-react-compiler@beta - npm install -D --save-exact prettier - ``` - - Now, add a new file `.prettierrc` to the root of the project: - - ```json - { - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "singleQuote": true - } - ``` - - And this is how your `eslint.config.js` should look like: - - ```js - import js from "@eslint/js"; - import globals from "globals"; - import reactHooks from "eslint-plugin-react-hooks"; - import reactRefresh from "eslint-plugin-react-refresh"; - import react from "eslint-plugin-react"; - import tseslint from "typescript-eslint"; - import eslintPluginPrettier from "eslint-plugin-prettier/recommended"; - import reactCompiler from "eslint-plugin-react-compiler"; - - export default tseslint.config( - { ignores: ["dist"] }, - { - extends: [ - js.configs.recommended, - ...tseslint.configs.strict, - eslintPluginPrettier, - ], - files: ["**/*.{ts,tsx}"], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - react, - "react-hooks": reactHooks, - "react-refresh": reactRefresh, - "react-compiler": reactCompiler, - }, - rules: { - ...reactHooks.configs.recommended.rules, - "react-refresh/only-export-components": [ - "warn", - { allowConstantExport: true }, - ], - "react-compiler/react-compiler": "error", - ...react.configs.recommended.rules, - ...react.configs["jsx-runtime"].rules, - }, - settings: { - react: { - version: "detect", - }, - }, - }, - ); - ``` - - 3. Husky - - Add Husky and configure it to run `lint` command on pre-commit. - ```sh - npm install --save-dev husky - ``` - You can follow the official [Husky documentation](https://typicode.github.io/husky/get-started.html) - 4. package.json commands - - Add the following npm scripts: - - `format:fix`: For running Prettier's --write command. - ```json - "format:fix": "prettier --write ." - ``` - You can check the final setup [here](https://github.com/kravaring/rs-react-app). - -5. Pick a RESTfull api which supports search and pagination (pagination might be referred as _offset_ and _limit_ params). E.g. https://pokeapi.co/, for Star Wars fans https://swapi.dev/api, for Star Trek fans https://stapi.co/api-documentation (OpenApi spec can be checked here https://editor.swagger.io/?url=https://stapi.co/api/v1/rest/common/download/stapi.yaml), or you can select another one complying with the requirements. - -6. All logical parts should be set into separate components such as CardList, Card, Search, Header, Main etc. - -7. **Use class components to get access to lifecycle events or state. Using hooks is forbidden at this stage. Patience, it won't last long.** + +2. Follow the requirements for the project setup listed [here](./project-setup.md) + +3. Pick a RESTfull api which supports search and pagination (pagination might be referred as _offset_ and _limit_ params). E.g. https://pokeapi.co/, for Star Wars fans https://swapi.dev/api, for Star Trek fans https://stapi.co/api-documentation (OpenApi spec can be checked here https://editor.swagger.io/?url=https://stapi.co/api/v1/rest/common/download/stapi.yaml), or you can select another one complying with the requirements. + +4. All logical parts should be set into separate components such as CardList, Card, Search, Header, Main etc. + +5. **Use class components to get access to lifecycle events or state. Using hooks is forbidden at this stage. Patience, it won't last long.** ## Points diff --git a/react/modules/tasks/forms.md b/react/modules/tasks/forms.md index eb9e4cd60..9def2b26d 100644 --- a/react/modules/tasks/forms.md +++ b/react/modules/tasks/forms.md @@ -1,25 +1,5 @@ # React forms. -## Technical Requirements - -1. Create a separate branch for this task. Branch name: "forms". For this task you will need to create a new application. -2. Language Requirement - - Use **TypeScript** for the project. -3. Project Setup - - Initialize the project using [Vite](https://vitejs.dev/guide/) with the [_react-ts_ template](https://vite.new/react-ts). -4. Code Quality Tools - 1. ESLint - - Set up ESLint to throw errors if TypeScript's _any_ type is used. - 2. Prettier - - Integrate Prettier for code formatting. - 3. Husky - - Add Husky and configure it to run linting on pre-commit. - 4. package.json commands - - Add the following npm scripts: - - `lint`: For running the lint command. - - `format:fix`: For running Prettier's --write command. -5. Add **React Hook Form**, **Yup**, **Redux Toolkit** and **React Router** to the application. - ## Application Requirements 1. Routing. There will be 3 routes: @@ -39,18 +19,24 @@ - autocomplete control to select country (all countries should be stored in the Redux store) Form should contain labels, which should be connected with inputs (look at **htmlFor**) 4. Validation - Implement validation according to the inputs description from p. 3. Use **Yup** for validation. Show errors either above each component, or below (but stick with one approach everywhere). Block submitting the form before all the errors are fixed (disable submit button). Good UX assumes that there are no "jumps" when showing errors. + Implement validation according to the inputs description from p. 3. Use **Yup** or **Zod** (but pick just one) for validation. Show errors either above each component, or below (but stick with one approach everywhere). Block submitting the form before all the errors are fixed (disable submit button). Good UX assumes that there are no "jumps" when showing errors. - Uncontrolled components should implement validation on submit - Approach with **React Hook Form** should implement live validation 5. After submitting the form On successful form submission redirect user to the main route with all the previously entered data. Make an indication for a newly entered data on the main route (e.g. show border in a different color for a few seconds, or a different background color) +## Technical Requirements + +1. Create a separate branch for this task. Branch name: "forms". For this task you will need to create a new application. +2. Follow the requirements for the project setup listed [here](./project-setup.md) +3. Add **React Hook Form**, **Yup** or **Zod**, **Redux Toolkit** and **React Router** to the application. + ## Points ### Student can get 100 points: - 3 routes (main and 2 routes for forms), Redux is set up and used to collect data from both forms, redirect to main route after submitting the form - **15 points** -- Validation works for both forms according to the requirements (error messages, blocking submit button), **Yup** is used for validation (10 points if works only for one form) - **20 points** +- Validation works for both forms according to the requirements (error messages, blocking submit button), **Yup** or **Zod** are used for validation (10 points if works only for one form) - **20 points** - Name, age, email, gender picker, accept T&C are implemented for both forms and collect data (if something doesn't work, score can be less) - **20 points** - Input for image is implemented for both forms, image is saved as base64 and dispaly on the main route after redirect - **15 points** - Passwords (with password strength) are implemented for both forms - **15 points** @@ -64,6 +50,6 @@ - Usage of _any_: **-20 points per each** - Usage of _ts-ignore_: **-20 points per each** - Presence of _code-smells_ (God-object, chunks of duplicate code), commented code sections: **-10 points per each** -- Validation is implemented without **Yup** - **-25 points** +- Validation is implemented without **Yup** or **Zod** - **-25 points** - Commits after the deadline: **-40 points** - Pull Request doesn't follow guideline (including checkboxes in Score) [PR example](https://docs.rs.school/#/en/pull-request-review-process?id=pull-request-description-must-contain-the-following): **-10 points** diff --git a/react/modules/tasks/performance.md b/react/modules/tasks/performance.md new file mode 100644 index 000000000..b621dc3f9 --- /dev/null +++ b/react/modules/tasks/performance.md @@ -0,0 +1,43 @@ +# React Performance + +## Application Requirements + +1. Fetch and Display Data + - Fetch country data from the [REST Countries API](https://restcountries.com/v3.1/all). + - Display a list of countries, including their name, population, region, and flag. +2. Add Filtering and Sorting + - Filter: Allow users to filter countries by region using a dropdown menu. + - Search: Add a search bar for users to search countries by name. + - Sort: Include an option to sort countries by population or name (ascending/descending). +3. Optimize the App for Performance + - useMemo: Use useMemo to memoize the filtered, searched, and sorted list of countries. + - useCallback: Use useCallback to memoize event handler functions for filtering, searching, and sorting. + - React.memo: Wrap components like individual country cards in React.memo to prevent unnecessary re-renders. + - key: Ensure proper use of key props for lists to avoid reconciliation issues. +4. Highlight countries visited by the user (you can store visited countries in the local storage). + +## Technical Requirements + +1. Create a separate branch for this task. Branch name: "performance". For this task, you will need to create a new application. +2. Follow the requirements for the project setup listed [here](./project-setup.md) + +## Points + +### Student can get 100 points: + +- Fetch and display country data, including name, population, region, and flag - **10 points** +- Filtering by region using a dropdown menu - **10 points** +- Searching countries by name using a search bar - **10 points** +- Sorting countries by population or name (ascending/descending) - **10 points** +- Optimization using useMemo, useCallback, React.memo, and proper use of key props - **50 points** +- Highlighting countries visited by the user, stored in local storage - **10 points** + +### Penalties + +- Usage of component libraries, e.g., Material UI, Ant Design: **-100 points** +- TypeScript isn't used: **-95 points** +- Usage of _any_: **-20 points per each** +- Usage of _ts-ignore_: **-20 points per each** +- Presence of _code-smells_ (God-object, chunks of duplicate code), commented code sections: **-10 points per each** +- Commits after the deadline: **-40 points** +- Pull Request doesn't follow guideline (including checkboxes in Score) [PR example](https://docs.rs.school/#/en/pull-request-review-process?id=pull-request-description-must-contain-the-following): **-10 points** diff --git a/react/modules/tasks/project-setup.md b/react/modules/tasks/project-setup.md new file mode 100644 index 000000000..901b568a1 --- /dev/null +++ b/react/modules/tasks/project-setup.md @@ -0,0 +1,102 @@ +# React Vite project setup with Eslint, Prettier and Husky + +## Technical requirements + +1. Language Requirement + - Use **TypeScript** for the project. +2. Project Setup + + - Initialize the project using [Vite](https://vitejs.dev/guide/) with the [_react-ts_ template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts). + ```sh + # npm 7+, extra double-dash is needed: + npm create vite@latest rs-react-app -- --template react-ts + ``` + +3. Code Quality Tools + + 1. ESLint + - ESlint v.9 is already a part of the _react-ts_ setup. + 2. Prettier + + - Integrate Prettier for code formatting. + You can execute the following command to add missing plugins: + + ```sh + npm install -D eslint-plugin-react eslint-plugin-prettier eslint-config-prettier eslint-plugin-react-compiler@beta + npm install -D --save-exact prettier + ``` + + Now, add a new file `.prettierrc` to the root of the project: + + ```json + { + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "singleQuote": true + } + ``` + + And this is how your `eslint.config.js` should look like: + + ```js + import js from "@eslint/js"; + import globals from "globals"; + import reactHooks from "eslint-plugin-react-hooks"; + import reactRefresh from "eslint-plugin-react-refresh"; + import react from "eslint-plugin-react"; + import tseslint from "typescript-eslint"; + import eslintPluginPrettier from "eslint-plugin-prettier/recommended"; + import reactCompiler from "eslint-plugin-react-compiler"; + + export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [ + js.configs.recommended, + ...tseslint.configs.strict, + eslintPluginPrettier, + ], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + react, + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + "react-compiler": reactCompiler, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + "react-compiler/react-compiler": "error", + ...react.configs.recommended.rules, + ...react.configs["jsx-runtime"].rules, + }, + settings: { + react: { + version: "detect", + }, + }, + }, + ); + ``` + + 3. Husky + - Add Husky and configure it to run `lint` command on pre-commit. + ```sh + npm install --save-dev husky + ``` + You can follow the official [Husky documentation](https://typicode.github.io/husky/get-started.html) + 4. package.json commands + - Add the following npm scripts: + - `format:fix`: For running Prettier's --write command. + ```json + "format:fix": "prettier --write ." + ``` + You can check the final setup [here](https://github.com/kravaring/rs-react-app). diff --git a/react/modules/tasks/redux.md b/react/modules/tasks/redux.md index 9b589f391..72880ebbb 100644 --- a/react/modules/tasks/redux.md +++ b/react/modules/tasks/redux.md @@ -1,21 +1,5 @@ # Redux. Redux Toolkit, RTK Query. Context api. -## Technical requirements - -1. Create a separate branch for this task from the previous branch task. Branch name: "app-state-management". -2. Redux Integration: - - Integrate Redux into your application. You'll need to set up the Redux store and reducers using Redux Toolkit. -3. RTK Query integration: - - RTK Query Implementation: Use Redux Toolkit Query (RTK Query) to make API calls and cache the results. This will modify your previous API call implementation; - - Use RTK Query to show whether the data is being loaded. Avoid prop-drilling, if it is required to show indicator in child component, put the respective flag in the store; - - Items returned for the current page should be stored in the store; - - Currently selected item details should be stored in the store. -4. Context API: - - Add context to control the application theme (light or dark). -5. Test Updates - - Update your tests to accommodate the changes introduced by Redux and RTK Query. - - Test the functionality related to Redux state and API calls. - ## Application Requirements 1. Selected items (Redux): @@ -32,6 +16,22 @@ - User should have an option to select one of the 2 themes (e.g. light or dark); - Selected theme should affect the appearance of the whole application +## Technical requirements + +1. Create a separate branch for this task from the previous branch task. Branch name: "app-state-management". +2. Redux Integration: + - Integrate Redux into your application. You'll need to set up the Redux store and reducers using Redux Toolkit. +3. RTK Query integration: + - RTK Query Implementation: Use Redux Toolkit Query (RTK Query) to make API calls and cache the results. This will modify your previous API call implementation; + - Use RTK Query to show whether the data is being loaded. Avoid prop-drilling, if it is required to show indicator in child component, put the respective flag in the store; + - Items returned for the current page should be stored in the store; + - Currently selected item details should be stored in the store. +4. Context API: + - Add context to control the application theme (light or dark). +5. Test Updates + - Update your tests to accommodate the changes introduced by Redux and RTK Query. + - Test the functionality related to Redux state and API calls. + ## Points A student can achieve a maximum of 200 points. diff --git a/react/modules/tasks/routing.md b/react/modules/tasks/routing.md index b4b8cf5bf..b207cb6d9 100644 --- a/react/modules/tasks/routing.md +++ b/react/modules/tasks/routing.md @@ -1,5 +1,16 @@ # React Routing. Tests. +## Application Requirements + +1. Add pagination: + - implement pagination for your existing item list + - display the current page in the browser URL using query parameters (e.g. ?page=2, e.g /search/2). + - the pagination component should appear after receiving the list of all items. +2. Main page displays search results. On item click page should be split into 2 section: + - left section will continue to display search results; + - right section should display details using Router Outlet (show loading indicator while making an additional call for details, add control for closing the section, also section should be closed when user clicks on the left section) + - reflect in the url that "Details" section has been opened for the selected item (e.g. /?frontpage=2&details=1). + ## Technical Requirements 1. Create a separate branch for this task from the previous task's branch. Branch name: "hooks-and-routing". @@ -36,17 +47,6 @@ 13. Lastly, update Husky to run tests on the pre-push hook, ensuring that tests are automatically executed before any code is pushed. -## Application Requirements - -1. Add pagination: - - implement pagination for your existing item list - - display the current page in the browser URL using query parameters (e.g. ?page=2, e.g /search/2). - - the pagination component should appear after receiving the list of all items. -2. Main page displays search results. On item click page should be split into 2 section: - - left section will continue to display search results; - - right section should display details using Router Outlet (show loading indicator while making an additional call for details, add control for closing the section, also section should be closed when user clicks on the left section) - - reflect in the url that "Details" section has been opened for the selected item (e.g. /?frontpage=2&details=1). - ## Points A student can achieve a maximum of 100 points.