Skip to content

Tati-Moon/react-labs

Repository files navigation

school-react-course-tasks

## TASK 1: React project setup. Class components. Error boundary.

Link: https://github.com/rolling-scopes-school/tasks/blob/master/react/modules/tasks/class-components.md

This project is a React application built using Vite, TypeScript, and modern development tools like ESLint, Prettier, and Husky. It follows best practices for code quality, formatting, and Git hooks.

Features

  • React with TypeScript: Type-safe React components.
  • Vite: Fast development server and build tool.
  • ESLint: Static code analysis for catching errors and enforcing coding standards.
  • Prettier: Automated code formatting for consistent style.
  • Husky: Git hooks for running linting and formatting before commits.
  • Error Boundary: Graceful error handling with a fallback UI.
  • Local Storage Integration: Persists search terms across sessions.
  • API Integration: Fetches data from a RESTful API (e.g., PokeAPI, SWAPI).

Setup

Steps

  1. Setup Node.js
  2. Install vite & run NPM install
npm create vite@latest rs-react-app -- --template react-ts
cd rs-react-app
npm install
npm run dev
  1. Set up ESLint and Prettier
npm install -D eslint-plugin-react eslint-plugin-prettier eslint-config-prettier eslint-plugin-react-compiler@beta
npm install -D --save-exact prettier

Add a new file .prettierrc to the root of the project:

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true
}

Update file eslint.config.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',
      },
    },
  }
);
  1. Husky Setup
npm install --save-dev husky
npx husky init
npx husky add .husky/pre-commit "npm run lint"
  1. Add package.json commands:
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext ts,tsx --fix",
    "format:fix": "prettier --write .",
    "prepare": "husky install"

Project Structure

/
├── src/
│   ├── components/
│   │   ├── Search.tsx
│   │   ├── CardList.tsx
│   │   ├── Card.tsx
│   │   └── ErrorBoundary.tsx
│   ├── App.tsx
│   └── main.tsx
├── .eslintrc.js
├── .prettierrc
├── package.json
├── tsconfig.json
├── README.md
└── .gitignore

Template

Successful response.

+-------------------------------------------------------+
|                                                       |
|  +------------------ Top controls ------------------+ |
|  | +--------------------------+ +-----------------+ | |
|  | | [Search Input Field]     | | [Search Button] | | |
|  | +--------------------------+ +-----------------+ | |
|  +--------------------------------------------------+ |
|                                                       |
|  +-------------------- Results ---------------------+ |
|  | +----------------------------------------------+ | |
|  | | Item Name  | Item Description                | | |
|  | +----------------------------------------------+ | |
|  | | [Item 1]   | [Description 1]                 | | |
|  | | [Item 2]   | [Description 2]                 | | |
|  | | ...        | ...                             | | |
|  +--------------------------------------------------+ |
|                                       [Error Button]  |
+-------------------------------------------------------+

Non-successful response.

+-------------------------------------------------------+
|                                                       |
|  +------------------ Top controls ------------------+ |
|  | +--------------------------+ +-----------------+ | |
|  | | [Search Input Field]     | | [Search Button] | | |
|  | +--------------------------+ +-----------------+ | |
|  +--------------------------------------------------+ |
|                                                       |
|  +-------------------- Results ---------------------+ |
|  |                                                  | |
|  |                 Error description                | |
|  |                                                  | |
|  +--------------------------------------------------+ |
|                                       [Error Button]  |
+-------------------------------------------------------+
## TASK 2: React Routing. Tests.

Link: https://github.com/rolling-scopes-school/tasks/blob/master/react/modules/tasks/routing.md

Implemented Features

Component Refactoring and Hooks

  • Converted all class components into functional components except the Error Boundary component.
  • Created a custom hook to restore the search query from local storage.
  • Used appropriate React lifecycle hooks.
  • Ensured state management was handled within individual components.

Routing

  • Implemented routing using React Router in SPA (non-SSR) mode.
  • Added a 404 page for non-existing routes.

Pagination

  • Implemented pagination for the existing item list (search results).
  • Updated the browser URL with the current page using query parameters.
  • Ensured the pagination component appears after receiving the full list of items.

Search and Item Details Display

  • Configured the main page to display search results.
  • On item click, the page was split into two sections:
    • The left section continued to display search results.
    • The right section displayed item details using Router Outlet.
  • Added a loading indicator while fetching additional details.
  • Implemented a close button for the details section.
  • Allowed closing the details section by clicking on the left section.
  • Reflected the state of the opened details section in the URL (e.g., /?frontpage=2&details=1).

Testing

  • Configured Jest as the test runner.
  • Ensured the test runner displayed test coverage.
  • Achieved at least 70% test coverage (excluding App.tsx).
  • Included only .tsx files in coverage.
  • Integrated React Testing Library for component testing.

Installation of Dependencies

To set up routing, the following library was installed:

npm install react-router-dom

The following packages were installed for testing:

npm install --save-dev jest @testing-library/react @testing-library/jest-dom ts-jest jest-environment-jsdom identity-obj-proxy

Branching and Development Workflow

All changes were implemented in a dedicated branch:

git checkout -b hooks-and-routing
## TASK 3: Redux. Redux Toolkit, RTK Query. Context api.

Link: https://github.com/rolling-scopes-school/tasks/blob/master/react/modules/tasks/redux.md

Theme Management (Context API)

To implement a custom theme selection feature, the following changes were made:

  • Created ThemeProvider and ThemeContext to manage the application's theme.
  • Added a theme selection option theme button to allow users to switch between light and dark themes.
  • Ensured the selected theme applies to the entire application by wrapping the app with ThemeProvider.

Installation of Dependencies

To support dynamic theming, Redux state management, and API requests, the following libraries were installed:

npm install classnames
npm install @reduxjs/toolkit axios react-redux

Purpose of Installed Packages

  • classnames – Used for conditionally applying CSS class names based on the selected theme.
  • @reduxjs/toolkit – Integrated Redux into the application, including setting up the store and reducers.
  • axios – Used for making API requests to fetch data.
  • react-redux – Provided React bindings for Redux to connect components with the store.

Redux State Management

To implement item selection and management using Redux, the following changes were made:

  • Each item in the dashboard now has a checkbox to allow selection.
  • Selected items are stored in the Redux store, ensuring persistence across page navigations.
  • Unselecting an item removes it from the store dynamically.
  • A flyout panel appears when at least one item is selected, displaying the total number of selected items and providing two actions:
    • "Unselect all" – Clears all selections and hides the flyout.
    • "Download" – Exports the list of selected items to a .csv file.

RTK Query Integration

RTK Query was implemented to optimize API interactions:

  • Replaced direct API calls with RTK Query, improving caching and reducing redundant requests.
  • Implemented a loading state in the store, ensuring smooth UI updates without prop-drilling.
  • Stored API responses in Redux, maintaining the current page’s data.

Branching and Development Workflow

All changes were implemented in a dedicated branch:

git checkout -b app-state-management

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors