Posts

React & State Management: All Concepts

Section 1: Fundamentals 1. Counter with increment, decrement, reset — useState Remember: prev is needed when the new state depends on the old state. When you're setting a hardcoded value like 0, you just pass 0 directly. Why:  reason prev matters — if multiple state updates happen in the same render cycle, React batches them. Using prev guarantees you're working off the latest state, not a stale snapshot. 2. Toggle show/hide paragraph — useState Remember: onClick={toggle} — pass the function reference, not the call. onClick={() => toggle()} — also fine, arrow function that calls toggle when clicked. onClick={toggle()} — calls toggle immediately during render, setVisible triggers re-render, toggle calls again, infinite loop. Why: JSX evaluates expressions inside {} during render. toggle() is an expression that executes immediately. React doesn't get a chance to attach it as a handler — it just runs it right there, state updates, component re-renders, runs again. ...

React Redux

Without Redux Increment, Decrement, Reset  Same state, modified by multiple components With Redux: Components dispatch actions → reducers update state → components re-render Centralizing this using Redux and Redux Toolkit npm install @reduxjs/toolkit react-redux 1. Install Redux Toolkit and React Redux. 2. Create a "store" using "configureStore". 3. Store holds all global application state. 4. Create "slice files" for each feature (user, counter, etc.). 5. Each slice contains initial state and reducers. 6. Redux Toolkit auto-generates actions from reducers. 7. Combine slice reducers inside the store. 8. Wrap `<App />` with `<Provider store={store}>`. 9. Use `useSelector` to read state in components. 10. Use `dispatch(action)` to update state. Multiple "Slices" Final Summary: Redux Toolkit is the modern, recommended way to use Redux The store holds all global state Slices organize state by feature useSelector reads state dispatch updat...

React: useOptimistic

Problem: Let's say we have a "๐Ÿ‘๐Ÿผ" button. When the user clicks on it, API call is made to save the value in the backend A message "Liked" is displayed if the save was successful But if the API call takes 5 seconds for the response, the UI looks laggy. Solution: useOptimistic hook: "Give me a temporary override of baseState while a transition is pending." Note: It does NOT store an independent state. It derives its value from the “base” (real) state. Rules: useOptimistic requires that there is some state that goes to ‘pending’ immediately after setting optimistic value There are several ways to make the component go to ‘pending’ like using startTransition When the pending transition stops, React stops using the optimistic value and re-renders using the real state value that your code updated. Lifecycle ๐Ÿ‘๐Ÿผclicked -> transition starts -> optimistic value used -> component in "pending" state -> API returns (component is no more in...

React: Concurrent Rendering

GITHUB Concurrent rendering is a way of scheduling rendering work . The developer tells React which updates are more important and which are less important. Since React runs on JavaScript, there is only one main thread. Imagine a kid building a Lego city. While building it, his sister falls down. He pauses building the Lego city (lower priority), helps his sister (higher priority), and then resumes building the city. React example Consider two state updates State update for the text typed in the input box State update for the computed results based on the input For a smooth user experience: The text the user types must appear immediately The computed results can appear with a slight delay So we tell React: Treat updates that affect the input value as high priority Treat updates that render derived or expensive results as low priority If React is busy rendering less important work and a high-priority update arrives, React can pause or abandon the low-priority rendering, update the input...

React: Routing - Lazy Loading and Protected routes

Image
The standard library used:  react-router-dom BASIC ROUTING 4 things needed A routing configuration A place to load the routes output <Outlet /> An initial element where all this can go <App /> A navbar main.jsx -> routes -> App -> Navbar + Outlet       Step 1: Routes.jsx import { Routes, Route } from "react-router-dom"; import App from "./App"; export default function GlobalRoutes() { return ( <Routes>   <Route path="/" element={<App />}>      <Route index path="/" element= { <Home/> } />      <Route path="/products" element= { <Products /> } />      <Route path="/profile" element= { <Profile /> } />      <Route path="*" element= { <Home/> } />    </Route>  </Routes> ) } Step 2: main.jsx import { BrowserRouter } from 'react-router-dom'createRoot(document.getElementById('root')).render( ...

React: Communication between components

Parent to Child: Props Child to Parent Callback Props (advanced props) Controlled Components useImperative hook  Nested Tree: useContext Sibling: Lift State Up PARENT TO CHILD: Props App.jsx Users.jsx <User name ={user} /> function User({ name }) {  return <h1> {name} </h1> } CHILD TO PARENT a) Callback Props (Advanced Props) Parent.jsx Child1.jsx export function Parent() {   function sayHello () {     alert(“hello triggered”)   }   <Child1 onSayHello ={ sayHello } /> } function Child1({ onSayHello }) {   return <button onClick={ onSayhello() }>          Click       </button> } b) Controlled Components Usually used in forms. Controlled components mean the parent owns the state, the child renders inputs, and every ch...

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

Image
There is a difference in the way JavaScript refences variables based on whether they are primitive or non-primitive Primitive Types: string, number, bigint, Boolean, symbol, null, undefined Non-Primitive: Arrays, Objects Each variable in JS is stored in a memory “box” Assignments: But when another variable tries to assign this value, JS thinks “wait, is this a primitive or non-primitive? Because if it is primitive, I will create a new box for this new variable with the same content. But if it’s not, I will just create a refence to the existing box” PRIMITIVE: Analogy: Let's say you have a note that says 5. You give a copy of this note to your friend.  Friend now updates this copy to 10. But your copy still says 5 let a = 5; let b = a; b = 10; //a remains unchanged NON-PRIMITIVE: Analogy: Let's say you have a note with address "123 Elm Street". In that house lives a cat named "Tom". You give a copy of this note to your friend. Friend now goes t...