You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+149-2Lines changed: 149 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -6204,7 +6204,7 @@ Technically it is possible to write nested function components but it is not sug
6204
6204
6205
6205
**[⬆ Back to Top](#table-of-contents)**
6206
6206
6207
-
274. Can useState take a function as an initial value?
6207
+
274. ### Can useState take a function as an initial value?
6208
6208
Yes, `useState` can take a function as an initial value, and this is a useful feature in React called **lazy initialization**. This function is also known as **initializer function**.
6209
6209
6210
6210
When you call useState(initialValue), you normally pass in a value directly:
@@ -6228,7 +6228,154 @@ Technically it is possible to write nested function components but it is not sug
6228
6228
```
6229
6229
6230
6230
**[⬆ Back to Top](#table-of-contents)**
6231
-
275.
6231
+
275. ### What types of values can `useState` hold?
6232
+
6233
+
The `useState` hook accepts different types of values.
6234
+
6235
+
* Primitives: `number`, `string`, `boolean`
6236
+
* Arrays
6237
+
* Objects
6238
+
* Functions
6239
+
* `null` or `undefined`
6240
+
6241
+
But you needs to be cautious with **reference types (objects/arrays)** because React compares old and new values **by reference**, so direct mutations won't trigger a re-render.
6242
+
For example, the correct and wrong ways of state updates as shown below,
6243
+
```js
6244
+
user.name="Sudheer"; //wrong way
6245
+
setUser(prev=> ({ ...prev, name:'Sudheer' })); //correct way
6246
+
```
6247
+
**[⬆ Back to Top](#table-of-contents)**
6248
+
276. ### What happens if you call `useState` conditionally?
6249
+
As per rules of React Hooks, hooks must be called unconditionally. For example, if you conditionally call it:
6250
+
```js
6251
+
if (someCondition) {
6252
+
const [state, setState] =useState(0);
6253
+
}
6254
+
```
6255
+
6256
+
React will throw a runtime error because it **relies on the order of Hook calls**, and conditional logic breaks that order.
6257
+
**[⬆ Back to Top](#table-of-contents)**
6258
+
277. ### Is useState Synchronous or Asynchronous?
6259
+
The `useState` hook is synchronous, but state updates are asynchronous. When you call `useState()`, it runs synchronously and returns the state variable and setter function as tuple.
6260
+
```js
6261
+
const [count, setCount] =useState(0);
6262
+
```
6263
+
This happens immediately during rendering.
6264
+
However, the state update function (**`**setState**`**) is asynchronous in the sense that it doesn't update the state immediately.
6265
+
React **batches** updates and applies them before the next render. You won’t see the updated value immediately after calling `setState`.
6266
+
**Example:**
6267
+
```js
6268
+
const [count, setCount] =useState(0);
6269
+
6270
+
functionhandleClick() {
6271
+
setCount(count +1);
6272
+
console.log(count); // ❗️Still logs the old value
6273
+
}
6274
+
```
6275
+
The > `console.log(count)` prints the **old value**, because the update hasn’t happened yet.
6276
+
6277
+
To see the updated state value, you can use `useEffect()` hook. It runs **after the component has re-rendered.** By the time `useEffect` runs:
6278
+
6279
+
* The component has been updated.
6280
+
* The **state contains the new value**.
6281
+
6282
+
```js
6283
+
importReact, { useState, useEffect } from'react';
6284
+
6285
+
functionCounter() {
6286
+
const [count, setCount] =useState(0);
6287
+
6288
+
consthandleClick= () => {
6289
+
setCount(count +1);
6290
+
console.log('Clicked count (old):', count); // Old value
6291
+
};
6292
+
6293
+
useEffect(() => {
6294
+
console.log('Updated count:', count); // New value
278. ### Can you explain how useState works internally?
6303
+
React’s hooks, including `useState`, rely on some internal machinery that keeps track of state **per component** and **per hook call** during rendering. Here's a simplified explanation of the internal mechanics:
6304
+
6305
+
#### 1. **Hook List / Linked List**
6306
+
6307
+
* React maintains a linked list or array of "hook states" for each component.
6308
+
* When a component renders, React keeps track of which hook it is currently processing via a cursor/index.
6309
+
* Each call to `useState()` corresponds to one "slot" in this list.
6310
+
6311
+
#### 2. **State Storage**
6312
+
6313
+
* Each slot stores:
6314
+
* The current state value.
6315
+
* A queue of pending state updates.
6316
+
6317
+
#### 3. **Initial Render**
6318
+
6319
+
* When the component first renders, React:
6320
+
* Creates a new slot for `useState` with the initial state (e.g., `0`).
6321
+
* Returns `[state, updaterFunction]`.
6322
+
6323
+
#### 4. **Updater Function**
6324
+
6325
+
* The updater function (`setCount`) is a closure that, when called:
6326
+
* Enqueues a state update to React's internal queue.
6327
+
* Schedules a re-render of the component.
6328
+
6329
+
#### 5. **Re-render and State Update**
6330
+
6331
+
* On the next render:
6332
+
* React processes all queued updates for each hook slot.
6333
+
* Updates the stored state value accordingly.
6334
+
* Returns the new state to the component.
6335
+
6336
+
#### 6. **Important: Hook Order**
6337
+
6338
+
* Hooks must be called in the same order on every render so React can match hook calls to their internal slots.
6339
+
* That’s why you can’t call hooks conditionally.
6340
+
6341
+
The pseudocode for internal implementation of `useState` looks like below,
6342
+
```js
6343
+
let hookIndex =0;
6344
+
consthooks= [];
6345
+
6346
+
functionuseState(initialValue) {
6347
+
constcurrentIndex= hookIndex;
6348
+
6349
+
if (!hooks[currentIndex]) {
6350
+
// First render: initialize state
6351
+
hooks[currentIndex] = {
6352
+
state: initialValue,
6353
+
queue: [],
6354
+
};
6355
+
}
6356
+
6357
+
consthook= hooks[currentIndex];
6358
+
6359
+
// Process queued updates
6360
+
hook.queue.forEach(update=> {
6361
+
hook.state=update(hook.state);
6362
+
});
6363
+
hook.queue= [];
6364
+
6365
+
// Define updater function
6366
+
functionsetState(action) {
6367
+
// action can be new state or function(state) => new state
0 commit comments