epam-ai-conductor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +46 -0
  2. package/bin/workshop.js +6 -0
  3. package/dist/auth-check.d.ts +1 -0
  4. package/dist/auth-check.js +45 -0
  5. package/dist/auth-check.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +156 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/content/content/module-1/task/module-1_home-task_components.md +257 -0
  10. package/dist/content/content/module-1/task/module-1_home-task_good_practices.md +69 -0
  11. package/dist/content/content/module-1/task/module-1_home-task_task.md +253 -0
  12. package/dist/content/content/module-1/tests/Button.test.tsx +22 -0
  13. package/dist/content/content/module-1/tests/CourseCard.test.tsx +64 -0
  14. package/dist/content/content/module-1/tests/CourseInfo.test.tsx +73 -0
  15. package/dist/content/content/module-1/tests/Courses.test.tsx +87 -0
  16. package/dist/content/content/module-1/tests/Header.test.tsx +23 -0
  17. package/dist/content/content/module-1/tests/Input.test.tsx +36 -0
  18. package/dist/content/content/module-1/tests/helpers.test.ts +13 -0
  19. package/dist/content/content/module-1/theory/module-1_elements-render.md +66 -0
  20. package/dist/content/content/module-1/theory/module-1_hooks_useEffect.md +178 -0
  21. package/dist/content/content/module-1/theory/module-1_hooks_useState.md +131 -0
  22. package/dist/content/content/module-1/theory/module-1_react.md +64 -0
  23. package/dist/content/content/module-1/theory/module-1_spa.md +74 -0
  24. package/dist/content/content/module-2/task/module-2_home-task_components.md +313 -0
  25. package/dist/content/content/module-2/task/module-2_home-task_good_practices.md +35 -0
  26. package/dist/content/content/module-2/task/module-2_home-task_task.md +210 -0
  27. package/dist/content/content/module-2/tests/App.test.tsx +54 -0
  28. package/dist/content/content/module-2/tests/Login.test.tsx +73 -0
  29. package/dist/content/content/module-2/tests/Registration.test.tsx +70 -0
  30. package/dist/content/content/module-2/tests/SearchBar.test.tsx +39 -0
  31. package/dist/content/content/module-2/theory/module-2_custom-hooks.md +201 -0
  32. package/dist/content/content/module-2/theory/module-2_hooks.md +117 -0
  33. package/dist/content/content/module-2/theory/module-2_react-router.md +328 -0
  34. package/dist/content/content/module-3/task/module-3_home-task_components.md +94 -0
  35. package/dist/content/content/module-3/task/module-3_home-task_good_practices.md +26 -0
  36. package/dist/content/content/module-3/task/module-3_home-task_task.md +170 -0
  37. package/dist/content/content/module-3/tests/App.test.tsx +54 -0
  38. package/dist/content/content/module-3/tests/Courses.test.tsx +87 -0
  39. package/dist/content/content/module-3/tests/CreateAuthor.test.tsx +44 -0
  40. package/dist/content/content/module-3/tests/CreateCourse.test.tsx +122 -0
  41. package/dist/content/content/module-3/theory/module-3_redux-hooks.md +194 -0
  42. package/dist/content/content/module-3/theory/module-3_state-actions-reducers.md +445 -0
  43. package/dist/content/content/module-4/task/module-4_home-task_components.md +187 -0
  44. package/dist/content/content/module-4/task/module-4_home-task_task.md +139 -0
  45. package/dist/content/content/module-4/tests/App.test.tsx +54 -0
  46. package/dist/content/content/module-4/tests/Courses.test.tsx +87 -0
  47. package/dist/content/content/module-4/tests/CreateCourse.test.tsx +122 -0
  48. package/dist/content/content/module-4/tests/Login.test.tsx +73 -0
  49. package/dist/content/content/module-4/theory/module-4_async-redux.md +99 -0
  50. package/dist/content/content/module-4/theory/module-4_private-routes.md +55 -0
  51. package/dist/content/content/module-5/task/module-5_home-task_instruction.md +68 -0
  52. package/dist/content/content/module-5/task/module-5_home-task_task.md +154 -0
  53. package/dist/content/content/module-5/tests/App.test.tsx +54 -0
  54. package/dist/content/content/module-5/tests/CourseCard.test.tsx +64 -0
  55. package/dist/content/content/module-5/tests/Courses.test.tsx +87 -0
  56. package/dist/content/content/module-5/tests/Header.test.tsx +23 -0
  57. package/dist/content/content/module-5/theory/module-5_react-testing-library_example.md +379 -0
  58. package/dist/content/content/module-5/theory/module-5_redux-writing-tests.md +246 -0
  59. package/dist/content/module-1/task/module-1_home-task_components.md +257 -0
  60. package/dist/content/module-1/task/module-1_home-task_good_practices.md +69 -0
  61. package/dist/content/module-1/task/module-1_home-task_task.md +253 -0
  62. package/dist/content/module-1/tests/Button.test.tsx +22 -0
  63. package/dist/content/module-1/tests/CourseCard.test.tsx +64 -0
  64. package/dist/content/module-1/tests/CourseInfo.test.tsx +73 -0
  65. package/dist/content/module-1/tests/Courses.test.tsx +87 -0
  66. package/dist/content/module-1/tests/Header.test.tsx +23 -0
  67. package/dist/content/module-1/tests/Input.test.tsx +36 -0
  68. package/dist/content/module-1/tests/helpers.test.ts +13 -0
  69. package/dist/content/module-1/theory/module-1_elements-render.md +66 -0
  70. package/dist/content/module-1/theory/module-1_hooks_useEffect.md +178 -0
  71. package/dist/content/module-1/theory/module-1_hooks_useState.md +131 -0
  72. package/dist/content/module-1/theory/module-1_react.md +64 -0
  73. package/dist/content/module-1/theory/module-1_spa.md +74 -0
  74. package/dist/content/module-2/task/module-2_home-task_components.md +313 -0
  75. package/dist/content/module-2/task/module-2_home-task_good_practices.md +35 -0
  76. package/dist/content/module-2/task/module-2_home-task_task.md +210 -0
  77. package/dist/content/module-2/tests/App.test.tsx +54 -0
  78. package/dist/content/module-2/tests/Login.test.tsx +73 -0
  79. package/dist/content/module-2/tests/Registration.test.tsx +70 -0
  80. package/dist/content/module-2/tests/SearchBar.test.tsx +39 -0
  81. package/dist/content/module-2/theory/module-2_custom-hooks.md +201 -0
  82. package/dist/content/module-2/theory/module-2_hooks.md +117 -0
  83. package/dist/content/module-2/theory/module-2_react-router.md +328 -0
  84. package/dist/content/module-3/task/module-3_home-task_components.md +94 -0
  85. package/dist/content/module-3/task/module-3_home-task_good_practices.md +26 -0
  86. package/dist/content/module-3/task/module-3_home-task_task.md +170 -0
  87. package/dist/content/module-3/tests/App.test.tsx +54 -0
  88. package/dist/content/module-3/tests/Courses.test.tsx +87 -0
  89. package/dist/content/module-3/tests/CreateAuthor.test.tsx +44 -0
  90. package/dist/content/module-3/tests/CreateCourse.test.tsx +122 -0
  91. package/dist/content/module-3/theory/module-3_redux-hooks.md +194 -0
  92. package/dist/content/module-3/theory/module-3_state-actions-reducers.md +445 -0
  93. package/dist/content/module-4/task/module-4_home-task_components.md +187 -0
  94. package/dist/content/module-4/task/module-4_home-task_task.md +139 -0
  95. package/dist/content/module-4/tests/App.test.tsx +54 -0
  96. package/dist/content/module-4/tests/Courses.test.tsx +87 -0
  97. package/dist/content/module-4/tests/CreateCourse.test.tsx +122 -0
  98. package/dist/content/module-4/tests/Login.test.tsx +73 -0
  99. package/dist/content/module-4/theory/module-4_async-redux.md +99 -0
  100. package/dist/content/module-4/theory/module-4_private-routes.md +55 -0
  101. package/dist/content/module-5/task/module-5_home-task_instruction.md +68 -0
  102. package/dist/content/module-5/task/module-5_home-task_task.md +154 -0
  103. package/dist/content/module-5/tests/App.test.tsx +54 -0
  104. package/dist/content/module-5/tests/CourseCard.test.tsx +64 -0
  105. package/dist/content/module-5/tests/Courses.test.tsx +87 -0
  106. package/dist/content/module-5/tests/Header.test.tsx +23 -0
  107. package/dist/content/module-5/theory/module-5_react-testing-library_example.md +379 -0
  108. package/dist/content/module-5/theory/module-5_redux-writing-tests.md +246 -0
  109. package/dist/content-loader.d.ts +7 -0
  110. package/dist/content-loader.js +26 -0
  111. package/dist/content-loader.js.map +1 -0
  112. package/dist/context-builder.d.ts +2 -0
  113. package/dist/context-builder.js +116 -0
  114. package/dist/context-builder.js.map +1 -0
  115. package/package.json +40 -0
@@ -0,0 +1,73 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { CourseInfo } from "../components/CourseInfo/CourseInfo";
4
+ import { formatCreationDate, getCourseDuration } from "../helpers";
5
+
6
+ const authorsList = [
7
+ { id: "1", name: "Author 1" },
8
+ { id: "2", name: "Author 2" },
9
+ { id: "3", name: "Author 3" },
10
+ { id: "4", name: "Author 4" },
11
+ ];
12
+
13
+ const course = {
14
+ id: "1",
15
+ title: "Course Title",
16
+ description: "Course Description",
17
+ authors: ["1", "3"],
18
+ creationDate: "08/03/2021",
19
+ duration: 120,
20
+ };
21
+
22
+ describe("CourseInfo", () => {
23
+ test("renders title correctly", () => {
24
+ render(<CourseInfo course={course} authorsList={authorsList} />);
25
+
26
+ const courseTitle = screen.getByRole("heading", { level: 1 });
27
+
28
+ expect(courseTitle.textContent).toBe("Course Title");
29
+ });
30
+
31
+ test("renders description correctly", () => {
32
+ render(<CourseInfo course={course} authorsList={authorsList} />);
33
+
34
+ const courseDescription = screen.getByText("Course Description");
35
+
36
+ expect(courseDescription).toBeInTheDocument();
37
+ });
38
+
39
+ test("renders course duration correctly", () => {
40
+ render(<CourseInfo course={course} authorsList={authorsList} />);
41
+
42
+ const courseDuration = screen.getByText(getCourseDuration(120));
43
+
44
+ expect(courseDuration).toBeInTheDocument();
45
+ });
46
+
47
+ test("renders course date correctly", () => {
48
+ render(<CourseInfo course={course} authorsList={authorsList} />);
49
+
50
+ const courseCreationDate = screen.getByText(
51
+ formatCreationDate(course.creationDate)
52
+ );
53
+ expect(courseCreationDate).toBeInTheDocument();
54
+ });
55
+
56
+ test("renders course authors' names correctly", () => {
57
+ render(<CourseInfo course={course} authorsList={authorsList} />);
58
+
59
+ const authorNames = screen
60
+ .getAllByRole("listitem")
61
+ .map((li) => li.textContent);
62
+
63
+ expect(authorNames).toEqual(["Author 1", "Author 3"]);
64
+ });
65
+
66
+ test("renders Back button correctly", () => {
67
+ render(<CourseInfo course={course} authorsList={authorsList} />);
68
+
69
+ const backButton = screen.getByRole("button", { name: "Back" });
70
+
71
+ expect(backButton).toBeInTheDocument();
72
+ });
73
+ });
@@ -0,0 +1,87 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { Courses } from "../components/Courses/Courses";
4
+
5
+ describe('Courses component', () => {
6
+ const mockedCoursesList = [
7
+ {
8
+ id: "1",
9
+ title: "Course 1",
10
+ description: "Course 1 description",
11
+ creationDate: "2022-01-01",
12
+ duration: 60,
13
+ authors: [
14
+ "27cc3006-e93a-4748-8ca8-73d06aa93b6d",
15
+ "f762978b-61eb-4096-812b-ebde22838167",
16
+ ],
17
+ },
18
+ {
19
+ id: "2",
20
+ title: "Course 2",
21
+ description: "Course 2 description",
22
+ creationDate: "2022-02-01",
23
+ duration: 90,
24
+ authors: ["df32994e-b23d-497c-9e4d-84e4dc02882f"],
25
+ },
26
+ ];
27
+ const onAddClick = jest.fn();
28
+
29
+ test("Should render list of courses", () => {
30
+ render(<Courses courseList={mockedCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
31
+
32
+ const courseElements = screen.getAllByTestId("courseCard");
33
+
34
+ expect(courseElements[0]).toBeInTheDocument();
35
+ expect(courseElements).toHaveLength(2);
36
+ });
37
+
38
+ test("Should render 'Add new course' button", () => {
39
+ render(<Courses courseList={mockedCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
40
+
41
+ const button = screen.getByText(/Add new course/);
42
+
43
+ expect(button).toBeInTheDocument();
44
+ });
45
+
46
+ test("Should render EmptyCourseList component if no courses", () => {
47
+ const mockedEmptyCoursesList: [] = [];
48
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
49
+
50
+ const emptyContainerElement = screen.getByTestId("emptyContainer");
51
+ const addButtonElement = screen.getByTestId("addCourse");
52
+
53
+ expect(emptyContainerElement).toBeInTheDocument();
54
+ expect(addButtonElement).toBeInTheDocument();
55
+ });
56
+ })
57
+
58
+ describe('EmptyCourseList', () => {
59
+ const mockedEmptyCoursesList: [] = [];
60
+ const onAddClick = jest.fn();
61
+
62
+ test("Should render title", () => {
63
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
64
+
65
+ const title = screen.getByText(/Your List Is Empty/);
66
+
67
+ expect(title).toBeInTheDocument();
68
+ });
69
+
70
+ test("Should render subtitle", () => {
71
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
72
+
73
+ const subTitle = screen.getByText(/Please use/);
74
+
75
+ expect(subTitle).toBeInTheDocument();
76
+ });
77
+
78
+ test("Should render button", () => {
79
+ render(<Courses courseList={mockedEmptyCoursesList} onAddClick={onAddClick} setSelectedCourseId={(id) => {}}/>);
80
+
81
+ const button = screen.getByText('ADD NEW COURSE');
82
+
83
+ expect(button).toBeInTheDocument();
84
+ });
85
+ })
86
+
87
+
@@ -0,0 +1,23 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { Header } from "../components/Header/Header";
4
+
5
+ describe('Header component', () => {
6
+ test("Should render logo", () => {
7
+ render(<Header />);
8
+
9
+ const imageElement = screen.getByRole("img");
10
+
11
+ expect(imageElement).toBeInTheDocument();
12
+ });
13
+
14
+ test("Should render logout button", () => {
15
+ render(<Header />);
16
+
17
+ const logoutButtonElement = screen.getByRole("button");
18
+
19
+ expect(logoutButtonElement).toBeInTheDocument();
20
+ });
21
+ })
22
+
23
+
@@ -0,0 +1,36 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, fireEvent, screen } from "@testing-library/react";
3
+ import { Input } from "../common/Input/Input";
4
+
5
+ describe('Input component', () => {
6
+ const placeholderTextMock = 'Enter a value';
7
+
8
+ test("should render input with provided label text", () => {
9
+ render(<Input labelText="Test Input" placeholderText={placeholderTextMock} />);
10
+
11
+ const inputElement = screen.getByLabelText("Test Input");
12
+ expect(inputElement).toBeInTheDocument();
13
+ });
14
+
15
+ test("should render input with provided placeholder text", () => {
16
+ const { getByPlaceholderText } = render(
17
+ <Input labelText='Test Input' placeholderText={placeholderTextMock} />
18
+ );
19
+
20
+ expect(getByPlaceholderText(placeholderTextMock)).toBeInTheDocument();
21
+ });
22
+
23
+ test("Should call provided callback for onChange event", () => {
24
+ const handleChange = jest.fn();
25
+
26
+ render(<Input labelText="Test Input" onChange={handleChange} placeholderText={placeholderTextMock}/>);
27
+
28
+ const inputElement = screen.getByLabelText("Test Input") as HTMLInputElement;
29
+ fireEvent.change(inputElement, { target: { value: "Hello" } });
30
+
31
+ expect(handleChange).toHaveBeenCalledTimes(1);
32
+ expect(inputElement.value).toBe("Hello");
33
+ });
34
+ })
35
+
36
+
@@ -0,0 +1,13 @@
1
+ import { formatCreationDate, getCourseDuration } from '../helpers';
2
+
3
+ test('formatCreationDate function returns formatted date', () => {
4
+ const date = '2022/01/01';
5
+ const formattedDate = formatCreationDate(date);
6
+ expect(formattedDate).toBe('2022.01.01');
7
+ });
8
+
9
+ test('getCourseDuration function returns formatted duration', () => {
10
+ expect(getCourseDuration(60)).toBe('01:00 hour');
11
+ expect(getCourseDuration(90)).toBe('01:30 hour');
12
+ expect(getCourseDuration(120)).toBe('02:00 hours');
13
+ });
@@ -0,0 +1,66 @@
1
+ ---
2
+ sidebar_position: 4
3
+ sidebar_label: 'Element Render'
4
+ title: 'Element Render'
5
+ ---
6
+
7
+ ## What is Element?
8
+
9
+ **Elements are the smallest building blocks of React apps.**
10
+
11
+ An element describes what you want to see on the screen:
12
+
13
+ ```jsx
14
+ const element = <h1>Hello, world</h1>;
15
+ ```
16
+
17
+ Unlike browser DOM elements, React elements are plain objects, and are cheap to create.
18
+ React DOM takes care of updating the DOM to match the React elements.
19
+ :::note
20
+ One might confuse elements with a more widely known concept of "components".
21
+ We will introduce components in the [next topic](components-and-props.mdx).
22
+ Elements are what components are "made of".
23
+ :::
24
+
25
+ ## Rendering an Element into the DOM
26
+ Let's say there is a `<div>` somewhere in your HTML file:
27
+
28
+ ```js
29
+ <div id="root"></div>
30
+ ```
31
+
32
+ It's called a **"root" DOM node** because everything inside it will be managed by React DOM.
33
+
34
+ Applications built with just React usually have a single root DOM node.
35
+ If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like.
36
+
37
+ To render a React element into a root DOM node, you need to create a React root and then pass the element to `root.render()`:
38
+
39
+ ```js
40
+ const element = <h1>Hello, world</h1>;
41
+
42
+ const root = ReactDOM.createRoot(document.getElementById('root'));
43
+
44
+ root.render(element);
45
+ ```
46
+
47
+ It displays "Hello, world" on the page.
48
+
49
+ ## React Only Updates What's Necessary
50
+ React DOM compares the element and its children to the previous one,
51
+ and only applies the DOM updates necessary to bring the DOM to the desired state.
52
+
53
+ It is possible because React uses [Virtual Dom](https://legacy.reactjs.org/docs/faq-internals.html).
54
+
55
+ ## Virtual DOM
56
+
57
+ **The virtual DOM (VDOM)** is a way of doing things in programming. It means having an ideal or "virtual" version of a user interface (UI) stored in the computer's memory. This virtual version is then matched up with the "real" DOM using a library like ReactDOM, and this matching process is called reconciliation.
58
+
59
+ This method makes it possible for React to work in a declarative way: *you tell React how you want the UI to look, and it makes sure the actual DOM matches that look*. This saves you from having to mess with attributes, handle events, or manually update the DOM, which you would have to do if you were building your app differently.
60
+
61
+ Because "virtual DOM" is more like a way of doing things than a specific technology, people might have different ideas about what it means. In the world of React, we often link the term "virtual DOM" with React elements because they are the objects that show the UI. However, React also uses internal objects called ["fibers"](https://github.com/acdlite/react-fiber-architecture) to keep extra information about the component tree. So, you could think of them as part of how React does its "virtual DOM" work.
62
+
63
+
64
+
65
+ ## Materials
66
+ 1. [Rendering Elements. Documentation](https://react.dev/learn/writing-markup-with-jsx)
@@ -0,0 +1,178 @@
1
+ ---
2
+ sidebar_position: 2
3
+ sidebar_label: 'useEffect'
4
+ title: 'useEffect'
5
+ ---
6
+
7
+ ## Why using useEffect hook?
8
+ The Effect Hook lets you perform side effects in function components:
9
+ ```jsx
10
+ import { useState, useEffect } from 'react';
11
+
12
+ const Button = () => {
13
+ const [count, setCount] = useState(0);
14
+
15
+ useEffect(() => {
16
+ // Update the document title using the browser API
17
+ document.title = `Button was clicked ${count} times`;
18
+ });
19
+
20
+ return (
21
+ <div>
22
+ <p>You clicked {count} times</p>
23
+ <button onClick={() => setCount(count + 1)}>
24
+ Click me
25
+ </button>
26
+ </div>
27
+ );
28
+ }
29
+ ```
30
+
31
+ `useEffect` accepts two parameters:
32
+ **The first one** is a callback which runs after render,
33
+ much like in [`componentDidMount`](/docs/module-1/state-and-life-cycle#mounting).
34
+ **The second** parameter is the effect dependency array.
35
+ If you want to run it on mount only, pass an empty array `[]`.
36
+
37
+ :::note
38
+ In the example above callback in the `useEffect` will be called with each render because the second argument was not passed.
39
+ :::
40
+
41
+ There are two common kinds of side effects in React components:
42
+ those that don’t require cleanup, and those that do.
43
+ Let’s look at this distinction in more detail.
44
+
45
+ ## Effects Without Cleanup
46
+
47
+ Sometimes, we need to do extra things after React updates the DOM. Things like:
48
+ * network requests,
49
+ * changing the DOM manually,
50
+ * keeping logs are
51
+
52
+ These are examples of effects that **don't need cleaning up**.
53
+
54
+ ### What does useEffect actually do?
55
+
56
+ When we use this Hook, we're telling React that our component needs to do
57
+ something after it's been shown.
58
+ React remembers the function we gave it (let's call it our "effect")
59
+ and runs it later, right after taking care of the DOM changes.
60
+
61
+ ### Why is useEffect put inside a component?
62
+
63
+ When we put useEffect inside the component,
64
+ it allows us to use any props right in the effect.
65
+ We don't need a special tool to read it; it's already available in the function.
66
+ Hooks work well with JavaScript closures, avoiding the need for special React-only
67
+ tools when JavaScript already provides a solution.
68
+
69
+ ### Does useEffect run every time the component shows?
70
+
71
+ Absolutely! By default, it runs both after the first show and after every update.
72
+ Instead of thinking about "when it's first shown" or "when it's updated,"
73
+ it might be simpler to see that effects happen "after each show."
74
+
75
+ ## Handling Effects that Need Cleanup
76
+
77
+ Earlier, we saw how to deal with effects that don't need cleaning up.
78
+ But some effects do, like setting up a subscription to an external data source.
79
+ In these cases, cleaning up is essential to avoid causing memory leaks. Let's explore an example:
80
+
81
+ You might be thinking that we’d need a separate effect to perform the cleanup.
82
+ But code for adding and removing a subscription is so tightly related that `useEffect` is designed to keep it together.
83
+ If your effect returns a function, React will run it when it is time to clean up:
84
+ ```jsx
85
+ import { useState, useEffect } from 'react';
86
+
87
+ const StatusComponent = ({user}) => {
88
+ const [isOnline, setIsOnline] = useState(null);
89
+
90
+ const updateStatus = (status) => {
91
+ setIsOnline(status.isOnline);
92
+ }
93
+
94
+ useEffect(() => {
95
+ // start to watch status
96
+ subscribeToStatus(user.id, updateStatus);
97
+
98
+ // stop to watch the status once the FriendStatus component is removed from DOM
99
+ // highlight-next-line
100
+ return () => {
101
+ unsubscribeFromStatus(user.id, updateStatus);
102
+ };
103
+ },[]);
104
+
105
+ return isOnline ? 'Online' : 'Offline';
106
+ }
107
+ ```
108
+
109
+ **Why did we add a function in our effect?**
110
+
111
+ This is the extra part that helps clean up effects if needed.
112
+ Each effect can include a function that takes care of cleaning up.
113
+ This way, we can manage the logic for both setting up and removing subscriptions in one place.
114
+
115
+ ## Tips
116
+ ### Use Multiple Effects to Separate Concerns
117
+ Just like you can use the State Hook more than once, you can also use several effects.
118
+ This lets us separate unrelated logic into different effects:
119
+ ```jsx
120
+ const StatusWithCounter = ({user}) => {
121
+ const [count, setCount] = useState(0);
122
+ const [isOnline, setIsOnline] = useState(null);
123
+
124
+ const updateStatus = (status) => {
125
+ setIsOnline(status.isOnline);
126
+ }
127
+
128
+ useEffect(() => {
129
+ document.title = `Button was clicked ${count} times`;
130
+ });
131
+
132
+ useEffect(() => {
133
+ subscribeToStatus(user.id, updateStatus);
134
+
135
+ return () => {
136
+ unsubscribeFromStatus(user.id, updateStatus);
137
+ };
138
+ });
139
+ // ...
140
+ }
141
+ ```
142
+
143
+ ### Making Code Clearer with Hooks
144
+
145
+ Hooks allow us to organize our code based on its purpose rather than a specific
146
+ lifecycle method name. React will handle each effect in the sequence they are listed.
147
+
148
+ ### Boosting Performance by Avoiding Unnecessary Effects
149
+
150
+ Sometimes, applying or cleaning up effects after every render
151
+ can slow things down. In such situations, you can instruct
152
+ React to skip certain effects if certain values haven't changed between renders.
153
+ To achieve this, provide an array as an extra option when using `useEffect`:
154
+
155
+ ```jsx
156
+ useEffect(() => {
157
+ document.title = `Button was clicked ${count} times`;
158
+ }, [count]); // Only re-run the effect if count changes
159
+ ```
160
+
161
+ In the example mentioned, we use `[count]` as the second part. What does this mean?
162
+
163
+ If `count` is 1, and the component re-renders with `count` still being 1,
164
+ React compares [1] from the last render with [1] from the next render.
165
+ Since all items in the array are the same (1 === 1), React skips the effect.
166
+
167
+ When we re-render with `count` changed to 2, React checks the items in the [1]
168
+ array from the previous render against the items in the [2] array from the next render.
169
+ This time, React reapplies the effect because 1 !== 2.
170
+ **If there are several items in the array, React will redo the effect even if only one
171
+ of them is different.**
172
+
173
+ This principle also applies to effects with a cleanup phase.
174
+
175
+
176
+ ## Materials
177
+ 1. [Effect Hook, React Documentation](https://react.dev/reference/react/useEffect)
178
+ 2. [React component lifecycle: React lifecycle methods & hooks](https://tsh.io/blog/react-component-lifecycle-methods-vs-hooks/#:~:text=React%20lifecycle%20method%20explained&text=As%20you%20probably%20know%2C%20each,a%20component%20from%20the%20DOM)
@@ -0,0 +1,131 @@
1
+ ---
2
+ sidebar_position: 1
3
+ sidebar_label: 'useState'
4
+ title: 'useState'
5
+ ---
6
+
7
+ ## Why you need hooks?
8
+ Hooks let you use state and other React features without writing a class.
9
+
10
+ ## What's a Hook?
11
+
12
+ A Hook is a special function that lets you "hook into" React features. For example, `useState` is a Hook that lets you add React state to function components.
13
+
14
+ ## When would I use a Hook?
15
+ If you write a function component and realize you need to add some state to it,
16
+ you do not need to convert it to a class. Now you can use a Hook inside the existing function component.
17
+
18
+ ## Using the State Hook
19
+
20
+ Let's look at this example:
21
+ ```jsx
22
+ import React, { useState } from 'react';
23
+
24
+ const Button = () => {
25
+ // Declare a new state variable, which we'll call "count"
26
+ // highlight-next-line
27
+ const [count, setCount] = useState(0);
28
+ }
29
+ ```
30
+ Understanding Hooks in Function Components
31
+
32
+ In a function component, the absence of `this` prevents the direct use of `this.state` (common in class components). Instead, the `useState` Hook is employed directly within the component.
33
+
34
+ ## What happens when we call useState?
35
+
36
+ It makes a "state variable."
37
+ We named ours `count`, but it could be named anything, even something funny like `banana`.
38
+ This helps us keep some values between function calls.
39
+ Usually, variables disappear when the function finishes, but React keeps state variables.
40
+
41
+ ## What is passed to useState as an argument?
42
+
43
+ The only argument passed to the `useState()` Hook is the initial state,
44
+ it can be a simple number or string if that suffices.
45
+ In the provided example, where we want to track the number of clicks, we pass `0` as the
46
+ initial state for our variable.
47
+
48
+ :::tip
49
+ If we wanted to store two different values in state, we would call `useState()` twice.
50
+ :::
51
+
52
+ **What does useState return?**
53
+ It returns a pair of values: the current state and a function that updates it.
54
+ This is why we write `const [count, setCount] = useState()`.
55
+ This is similar to `this.state.count` and `this.setState` in a class,
56
+ except you get them in a pair.
57
+ If you're not familiar with the syntax we used, we'll come back to it at the bottom of this page.
58
+
59
+ Let's come back to our example. Now that we know what the useState Hook does, our example should make more sense:
60
+ ```jsx
61
+ import React, { useState } from 'react';
62
+
63
+ const Button = () => {
64
+ // Declare a new state variable, which we'll call "count"
65
+ // highlight-next-line
66
+ const [count, setCount] = useState(0);
67
+ }
68
+ ```
69
+
70
+ We declare a state variable called `count`, and set it to `0`.
71
+ **React will remember its current value between re-renders**,
72
+ and provide the most recent one to our function.
73
+ If we want to update the current `count`, we can call `setCount`.
74
+
75
+ ### Reading State
76
+ In a function component, we can use `count` directly:
77
+ ```jsx
78
+ <p>You clicked {count} times</p>
79
+ ```
80
+
81
+ ### Updating State
82
+
83
+ We have `setCount` and `count` as variables so we can pass new count value to the function:
84
+
85
+ ```jsx
86
+ <button onClick={() => setCount(count + 1)}>
87
+ Click me
88
+ </button>
89
+ ```
90
+
91
+ Let's now recap what we learned line by line and check our understanding.
92
+
93
+ ```jsx
94
+ 1: import { useState } from 'react';
95
+ 2:
96
+ 3: const Button = () => {
97
+ 4: const [count, setCount] = useState(0);
98
+ 5:
99
+ 6: return (
100
+ 7: <div>
101
+ 8: <p>You clicked {count} times</p>
102
+ 9: <button onClick={() => setCount(count + 1)}>
103
+ 10: Click me
104
+ 11: </button>
105
+ 12: </div>
106
+ 13: );
107
+ 14: }
108
+ ```
109
+ **Line 1:**
110
+ We import the `useState` Hook from React.
111
+ It lets us keep local state in a function component.
112
+
113
+
114
+ **Line 4:**
115
+ Inside the `Example` component, we declare a new state variable by calling the `useState` Hook.
116
+ It returns a pair of values, to which we give names.
117
+ We're calling our variable `count` because it holds the number of button clicks.
118
+ We initialize it to zero by passing `0` as the only `useState` argument.
119
+ The second returned item is itself a function. It lets us update the `count` so we'll
120
+ name it `setCount`.
121
+
122
+
123
+ **Line 9:**
124
+ When the user clicks, we call `setCount` with a new value.
125
+ React will then re-render the `Button` component, passing the new count value to it.
126
+
127
+
128
+ ## Materials
129
+ 1. [React Documentation. useState Hook](https://react.dev/reference/react/useState)
130
+ 2. [Rules of Hooks. React Documentation](https://react.dev/reference/rules/rules-of-hooks)
131
+
@@ -0,0 +1,64 @@
1
+ ---
2
+ sidebar_position: 2
3
+ sidebar_label: 'What is React?'
4
+ title: 'What is React?'
5
+ ---
6
+ Now let's get acquainted with the [React library](https://react.dev/) and start with the one who created and is engaged in further support of it.
7
+
8
+ ## A Quick History Snippet
9
+
10
+ React JS, a really famous technology, started at Facebook. The company wanted React JS to be a JavaScript library for making user interfaces (UI). Jordan Walke made it, and at first, he called it "FaxJS." Later on, Facebook decided to use it to make their mobile app better. Now, React has a large community, and it keeps updating it all the time.
11
+
12
+ ## What is React?
13
+
14
+ **React is an open-source JavaScript library** that is used for building user interfaces specifically
15
+ for single-page applications.
16
+ It’s used for handling the view layer for **web** and **mobile** apps.
17
+
18
+ ## Why React?
19
+
20
+ React properties include the following:
21
+ &#11088; React is **declarative**
22
+ &#11088; React is **simple**
23
+ &#11088; React is **component based**
24
+ &#11088; React supports **server side rendering**
25
+ &#11088; React is **extensive**
26
+ &#11088; React is **fast**
27
+ &#11088; React is **easy to learn**
28
+
29
+ ## React has several impressive features:
30
+
31
+ 1. [**JSX**](jsx.mdx) (we will learn more about this later)
32
+
33
+
34
+ 2. **React Native.**
35
+ React has native libraries that Facebook announced in 2015, which allow the React architecture to be used in native applications such as iOS and Android.
36
+
37
+
38
+ 3. **Single-Way data flow.**
39
+ In React, a set of immutable values are passed to the component's renderer as properties in its HTML tags. The component cannot directly modify any properties, but it can pass a callback function that enables modifications to be made.
40
+ This entire process is commonly referred to as **“properties flow down; actions flow up”**.
41
+
42
+
43
+ 4. **Virtual DOM.**
44
+ React creates an in-memory data structure cache that computes the changes made and updates the browser accordingly. This unique feature allows programmers to code as if the entire page is rendered on each change, while the React library only renders the components that have actually changed.
45
+
46
+
47
+ ## A few more pros of the React
48
+
49
+ 1. **Easy to learn.**
50
+ React is relatively easy to understand for anyone with basic knowledge of HTML, CSS, and JavaScript. It has a lower entry threshold compared to other libraries/frameworks, allowing you to start creating a web application quickly.
51
+
52
+
53
+ 2. **Performance.**
54
+ Many developers faced performance issues when the DOM was updated, which slowed down the application. React addressed this problem by introducing the virtual DOM. The React Virtual DOM exists entirely in memory and is a representation of the web browser's DOM. You no longer need to manually create and remove DOM elements, as React will handle it for you.
55
+
56
+
57
+ 3. **Testability.**
58
+ React applications are straightforward to test. React views can be treated as functions of the state, allowing us to manipulate the state passed to the React view and examine the output and triggered actions, events, functions, and so on.
59
+
60
+
61
+
62
+
63
+
64
+