8000 Hooks Added · mutasim77/ReactJS-Notebook@c44612b · GitHub
[go: up one dir, main page]

Skip to content

Commit c44612b

Browse files
committed
Hooks Added
1 parent 8998fba commit c44612b

File tree

12 files changed

+657
-723
lines changed

12 files changed

+657
-723
lines changed

docs/Hooks/Introduction.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
id: react-hooks
3+
title: Introduction
4+
description: Quick introduction
5+
sidebar_position: 1
6+
---
7+
8+
import DocCardList from '@theme/DocCardList';
9+
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
10+
11+
# React Hooks 🎣
12+
13+
React Hooks are a powerful feature introduced in React 16.8 that allows developers to add state and other React features to functional components. Prior to the introduction of hooks, state management and other complex logic could only be implemented in class components using lifecycle methods. With hooks, developers can now write more concise and reusable code by leveraging functions instead of classes.
14+
15+
Hooks provide several benefits in React development. Firstly, they simplify the management of component state. With the "useState" hook, you can add state to a functional component, eliminating the need for a class-based component. This results in cleaner and more readable code.
16+
17+
Secondly, hooks enable the reuse of logic across components. The "useEffect" hook allows you to perform side effects such as data fetching, subscriptions, or manually changing the DOM after rendering. By encapsulating such logic in a custom hook, you can easily share it across different components, improving code maintainability and reducing duplication.
18+
19+
Another advantage of hooks is the ability to create custom hooks. Custom hooks are functions that combine multiple built-in hooks and encapsulate complex logic into reusable units. This promotes code modularity and makes it easier to share code between projects or within a team.
20+
21+
Here is a list of some commonly used React hooks:
22+
23+
<DocCardList items={useCurrentSidebarCategory().items}/>
24+
25+
These hooks cover a wide range of functionality and help streamline the development process in React.

docs/Hooks/useCallback.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
id: react-hook-useCallback
3+
title: useCallback
4+
description: Memoizes a function to prevent unnecessary re-rendering of components that depend on it.
5+
sidebar_position: 4
6+
---
7+
8+
**useCallback** is a React hook that allows you to optimize the performance of your React components by memoizing a function. In simple terms, it helps you avoid unnecessary re-creation of functions on each render.
9+
10+
When you define a function inside a component, it gets recreated every time the component re-renders, even if the function itself hasn't changed. This can lead to performance issues, especially if you pass that function as a prop to child components, as it may cause unnecessary re-renders in those components too.
11+
12+
Here's where useCallback comes in handy. It memoizes a function and returns a memoized version of it. The memoized version will only change if any of the dependencies provided to useCallback change. If the dependencies remain the same, useCallback will return the same memoized function from the previous render.
13+
14+
Here's an example to illustrate its usage:
15+
16+
```jsx
17+
import React, { useState, useCallback } from 'react';
18+
19+
const CounterButton = ({ onClick }) => {
20+
console.log('CounterButton rendering');
21+
return (
22+
<button onClick={onClick}>
23+
Click me!
24+
</button>
25+
);
26+
};
27+
28+
const Counter = () => {
29+
const [count, setCount] = useState(0);
30+
31+
const handleClick = useCallback(() => {
32+
setCount(count + 1);
33+
}, [count]);
34+
35+
console.log('Counter rendering');
36+
37+
return (
38+
<div>
39+
<p>Count: {count}</p>
40+
<CounterButton onClick={handleClick} />
41+
</div>
42+
);
43+
};
44+
```
45+
46+
In the example above, we have a Counter component that renders a CounterButton component. Whenever the Counter component re-renders, it will create a new handleClick function because it references the count state value. However, by using **useCallback**, we can optimize this behavior.
47+
48+
By providing [count] as the dependency array to useCallback, it ensures that the handleClick function will only be re-created if the count value changes. If count remains the same, useCallback will return the previously memoized handleClick function.
49+
50+
This optimization can be helpful when passing handleClick as a prop to child components because it prevents unnecessary re-renders in those components if the dependencies haven't changed.
51+
52+
Remember to include all the dependencies that the function relies on in the dependency array to ensure the correct behavior of **useCallback**.

docs/Hooks/useContext.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
id: react-hook-useContext
3+
title: useContext
4+
description: Lets you read and subscribe to context from your component.
5+
sidebar_position: 8
6+
---
7+
8+
React context provides data to components no matter how deep they are in the components tree. The context is used to manage global data, e.g. global state, theme, services, user settings, and more.
9+
10+
## How to use the context ? 🤓
11+
Using the context in React requires 3 simple steps: creating the context, providing the context, and consuming the context.
12+
13+
- A. Creating the context
14+
15+
The built-in factory function createContext(default) creates a context instance:
16+
17+
```jsx
18+
// context.js
19+
import { createContext } from 'react';
20+
21+
export const Context = createContext('Default Value');
22+
```
23+
24+
The factory function accepts one optional argument: the **default** value.
25+
26+
- B. Providing the context
27+
28+
**Context.Provider** component available on the context instance is used to provide the context to its child components, no matter how deep they are.
29+
30+
To set the value of context use the **value** prop available on the `<Context.Provider value={value} />` :
31+
32+
```jsx
33+
import { Context } from './context';
34+
35+
function Main() {
36+
const value = 'My Context Value';
37+
return (
38+
<Context.Provider value={value}>
39+
<MyComponent />
40+
</Context.Provider>
41+
);
42+
}
43+
```
44+
45+
Again, what's important here is that all the components that'd like later to consume the context have to be wrapped inside the provider component.
46+
47+
If you want to change the context value, simply update the value prop.
48+
49+
- C. Consuming the context
50+
51+
Consuming the context can be performed in 2 ways.
52+
53+
The first way, the one I recommend, is to use the ```useContext(Context)``` React hook:
54+
55+
```jsx
56+
import { useContext } from 'react';
57+
import { Context } from './context';
58+
59+
function MyComponent() {
60+
const value = useContext(Context);
61+
62+
return <span>{value}</span>;
63+
}
64+
```
65+
66+
The hook returns the value of the context: `value = useContext(Context)`. The hook also makes sure to re-render the component when the context value changes.
67+
68+
The second way is by using a render function supplied as a child to Context.Consumer special component available on the context instance:
69+
70+
```jsx
71+
import { Context } from './context';
72+
73+
function MyComponent() {
74+
return (
75+
<Context.Consumer>
76+
{value => <span>{value}</span>}
77+
</Context.Consumer>
78+
);
79+
}
80+
```
81+
82+
Again, in case the context value changes, `<Context.Consumer>` will re-call its render function.
83+
84+
![useContext pic](https://github.com/mutasim77/ReactJS-Notebook/assets/96326525/ec4f7e4c-24e4-49ee-96b3-a7f4b6f2d8cd)
85+
86+
You can have as many consumers as you want for a single context. If the context value changes "by changing the value prop of the provider `<Context.Provider value={value} />`", then all consumers are immediately notified and re-rendered.
87+
88+
If the consumer isn't wrapped inside the provider, but still tries to access the context value using `useContext(Context)` or `*<Context.Consumer>`*, then the value of the context would be the default value argument supplied to `*createContext(defaultValue)*` factory function that had created the context.
89+
90+
## When do you need context? 🤓
91+
92+
The main idea of using the context is to allow your components to access global data and re-render when that global data is changed. Context solves the props drilling problem: when you have to pass down props from parents to children.
93+
94+
You can hold inside the context:
95+
96+
- global state
97+
- theme
98+
- application configuration
99+
- authenticated user name
100+
- user settings
101+
- preferred language
102+
- a collection of services
103+
104+
On the other side, you should think carefully before deciding to use context in your application.
105+
106+
First, integrating the context adds complexity. Creating a context, wrapping everything in a provider, and using the useContext() in every consumer — increases complexity.
107+
108+
Secondly, adding context complicates unit testing of components. During testing, you'll have to wrap the consumer components into a context provider. Including the components that are indirectly affected by the context — the ancestors of context consumers!
109+
110+
## Conclusion 🤓
111+
The context in React lets you supply child components with global data, no matter how deep they are in the components tree.
112+
113+
Using the context requires 3 steps: creating, providing, and consuming the context.
114+
115+
When integrating the context into your application, consider that it adds a good amount of complexity. Sometimes drilling the props through 2-3 levels in the hierarchy isn't a big problem.

docs/Hooks/useEffect.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
id: react-hook-useEffect
3+
title: useEffect
4+
description: Performs side effects after rendering, such as data fetching or subscriptions.
5+
sidebar_position: 3
6+
---
7+
8+
*useEffect* is a hook in React that allows you to perform side effects in functional components. Side effects can include things like fetching data from an API, subscribing to events, or updating the document title. It's called a "side effect" because it doesn't directly affect the rendering of your component, but rather deals with other interactions outside of it.
9+
10+
Here's a breakdown of how to use useEffect:
11+
12+
Import the useEffect hook from the React library:
13+
14+
```jsx
15+
import React, { useEffect } from 'react';
16+
```
17+
Use the useEffect hook inside your functional component:
18+
19+
```jsx
20+
function MyComponent() {
21+
useEffect(() => {
22+
// Side effect code goes here
23+
});
24+
25+
return (
26+
// JSX code for your component
27+
);
28+
}
29+
```
30+
31+
The first argument of useEffect is a function that will be called after the component renders. This function is where you can place your side effect code. It runs every time the component renders by default.
32+
33+
```jsx
34+
useEffect(() => {
35+
// Side effect code
36+
});
37+
```
38+
39+
You can also provide a second argument to useEffect that determines when the effect should run. This is an optional array of dependencies. If any of the dependencies change between renders, the effect will be triggered again. If the dependency array is empty, the effect will only run once when the component mounts, and not again.
40+
41+
```jsx
42+
useEffect(() => {
43+
// Side effect code
44+
}, [dependency1, dependency2]);
45+
```
46+
Now let's look at some examples:
47+
48+
1. Fetching data from an API:
49+
```jsx
50+
useEffect(() => {
51+
fetch('https://api.example.com/data')
52+
.then(response => response.json())
53+
.then(data => {
54+
// Do something with the fetched data
55+
});
56+
}, []);
57+
```
58+
In this example, the effect runs only once when the component mounts because the dependency array is empty.
59+
60+
2. Subscribing to an event:
61+
```jsx
62+
useEffect(() => {
63+
const handleClick = () => {
64+
// Handle the click event
65+
};
66+
67+
window.addEventListener('click', handleClick);
68+
69+
return () => {
70+
window.removeEventListener('click', handleClick);
71+
};
72+
}, []);
73+
```
74+
Here, the effect adds an event listener for the click event when the component mounts, and removes it when the component unmounts. The empty dependency array ensures that the effect only runs once.
75+

docs/Hooks/useMemo.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
id: react-hook-useMemo
3+
title: useMemo
4+
description: Memoizes a value to prevent expensive computations on every render.
5+
sidebar_position: 5
6+
---
7+
8+
**useMemo** is another React hook that allows you to optimize the performance of your React components by memoizing a value. It's similar to **useCallback**, but instead of memoizing a function, it memoizes a computed value.
9+
10+
In React, there are situations where you may have expensive computations or calculations that are performed within a component. These computations can take up processing power and slow down your application, especially if they are re-executed on every render, even if the dependencies haven't changed.
11+
12+
Here's where useMemo comes in handy. It allows you to memoize the result of a computation and only recompute it if the dependencies provided to useMemo have changed. If the dependencies remain the same, useMemo will return the previously memoized value from the previous render, saving unnecessary calculations.
13+
14+
Here's an example to illustrate its usage:
15+
16+
```jsx
17+
import React, { useState, useMemo } from 'react';
18+
19+
const ExpensiveComponent = ({ value }) => {
20+
const expensiveResult = useMemo(() => {
21+
console.log('Performing expensive computation...');
22+
// Perform some complex calculations based on the value
23+
return value * 2;
24+
}, [value]);
25+
26+
console.log('ExpensiveComponent rendering');
27+
28+
return (
29+
<div>
30+
<p>Value: {value}</p>
31+
<p>Expensive Result: {expensiveResult}</p>
32+
</div>
33+
);
34+
};
35+
36+
const App = () => {
37+
const [count, setCount] = useState(0);
38+
39+
const handleClick = () => {
40+
setCount(count + 1);
41+
};
42+
43+
console.log('App rendering');
44+
45+
return (
46+
<div>
47+
<button onClick={handleClick}>Increment</button>
48+
<ExpensiveComponent value={count} />
49+
</div>
50+
);
51+
};
52+
```
53+
54+
In the example above, we have an **ExpensiveComponent** that performs some computationally expensive calculations based on the value prop it receives. Whenever the **ExpensiveComponent** re-renders, it would recompute the expensive result, even if the value prop hasn't changed. This can impact performance if the calculations are complex.
55+
56+
By using useMemo, we can optimize this behavior. By providing [value] as the dependency array to useMemo, it ensures that the expensive computation will only be re-executed if the value prop changes. If the value remains the same, useMemo will return the previously memoized value.
57+
58+
This optimization can be helpful in scenarios where you have expensive computations, heavy data processing, or complex transformations that depend on certain values. By memoizing the result with useMemo, you can avoid unnecessary recalculations and improve the performance of your components.
59+
60+
Remember to include all the dependencies that the computation relies on in the dependency array to ensure the correct behavior of **useMemo**.

0 commit comments

Comments
 (0)
0