React is a JavaScript library for building user interfaces. It's used for creating reusable UI components and managing state changes in the application.
React DOM - Bridges the gap between react and browser to manipulate DOM.
const heading = React.createElement('h1', {}, 'Hello, React!');
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(heading);
React Element is created using createElement(heading), it is an object (not an html element)
We cannot create tags like this as it is painful and takes time, hence we have an easier way known as *JSX
Root.render - replaces everything inside the root if there is any element.
npm - A repo for all the packages (a.k.a dependencies).
package.json - A configuration for our app npm.
bundler - Bundling(html/css/JS) - cleaned, chunking, compressed, minified - basically bundles our app eg: webpack, parcel, vite
- npm install -D parcel (Here -D means dev dependency, there is another normal version too for production)
- "parcel": "^2.12.0" (here, caret - ^ means upgrade to a minor version if there is any) - *Recommended*
- "parcel": "~2.12.0" (here, tilde - ~ means upgrade to a major version if there is any).
package-lock.json - keeps a track of the exact version of all the dependencies.
node_modules - like a database for our dependencies.
transitive dependencies - parcel can have its own dependencies too (babel), and in turn those dependencies can have dependencies too and hence this is known as transitive dependencies.
npm vs npx - installing a package vs executing a package without installing.
React via CDN - Bad practice, heavy network calls, version issues since URL is hardcoded with a version number that would be required to change whenever there is a latest version of react.
React as a package via node_modules - Easier, available at your fingertips, no network calls, version is managed by package.json
parcel - A bundler - It does -> Dev builld - local server, - HMR (Hot Module Replacement) -> Refreshes when we use update any file and uses file watching algorithms to implement this. - Caching - Faster Builds - Image optimizaton - Minification - Compressing - Consistent Hashing - Code Splitting - Differential Bundling - to support older browsers - Diagnostics - Error handling - HTTPS - Tree Shaking - remove unused codes. - Different dev and production bundles
npm run start === npm start - setting start and build command within parcel. React vs JSX - Both are different - React elements can be created without JSX JSX - A syntax extension for JavaScript, syntax sugar for React.createElement() - JS - It looks like HTML but its not. - It is transpiled so that the JS engine in the browser can understand with normal core JS using babel & parcel - Attributes in JSX should be in camelCase. - JSX also saves us from Cross-site scripting attack by sanitizing data. Babel - Converts JSX to native JS code - Powerful package - Transpiler - Also translates modern ES6+ JS code for unsupported older browsers
React Component - Anything can be a component - a button, header, footer, cards etc. Two types of Components -> Class Based & Function based
Functional Components - A function that returns JSX (React Element) Component Composition - Composing two or more components together. Expressions in JSX - With just {} and anything within this is an expression. Calling functions in JSX - It is possible -> {Title()} since functional components are functions in the end.
- App designing....
Props - Just like normal function arguments
- When you want to pass the dynamic data to the components - Say hello to Props
Config Driven UI - A website UI driven by Data using Map - to loop re-usable components passing keys - to uniquely identifying looping elements if not given, react always re-renders everything (like humans forget password, type all over again) - Not recommended to use index from the map/forEach as it messes up the re-ordering issues.
Why React? - Makes your developer experience easier and faster (DOM Manipulation, Virtual DOM, Diff Algo, Reconciliation) - Write less code - Optimization
Folder Structure - React has no opinions on folder structure, but best to follow industry standards. -
Two types of Export/Import Unnamed/Default Export/import -> - Exporting components at once - export default Component; import component from ""; named Export/import - Exporting all components from a single file. - export const Component; import {component} from ""; NOTE - Combination of both unnamed and named export/import is also possible.
Event Handlers - <button className="filter-btn" onClick={()=> { console.log("Clicked"); }} >Filter - Using arrow function to pass the event handler function to the component.
React Hooks - A normal JS utility function given by React with super-powers. useState() - To create and store the state variable in functional components to maintain the state. - Whenever state is updated/changed in react, it re-renders that component - To keep the state/Data Layer in sync with the UI Layer
Reconciliation Algorithm
- React creates a copy of DOM known as - Virtual DOM(Representation of an actual DOM)
Virtual DOM (Object representation in JavaScript)
- All JSX (html like syntax) which is a react element inside which is an object in the Virtual DOM. Diff Algorithm
- Once there is a change in the state, it finds the difference between the old virtual DOM and the updated Virtual DOM.
- And based on this difference, it updates the ACTUAL DOM
React Fiber - React Fiber is the re-implementation of Reactβs core algorithm introduced in React 16. It allows React to break down rendering work into smaller units, enabling better control over rendering and the ability to pause, resume, or abort work. - It provides a more flexible, incremental rendering mechanism.
Monolith vs Microservices
- Monolith: All the services(auth, api, db, sms) are bundled together in a single application.
- Microservices: Each service is a separate application and communicates with each other using APIs.
Traditional Way: Load -> APIs -> Render Another way (React uses): Load -> Render -> API -> Render
useEffect() - To handle side effects like API calls, DOM manipulation, etc. - It is used to fetch data from the server and update the state of the component. Syntax: useEffect(callback, dependency array) - It is called when a component is rendered/render cycle is completed
CORS Policy - When a browser blocks calling of one origin from another origin (Swiggy API and localhost)
Swiggy API Call - Done with making res list api call from Swiggy
Shimmer UI - Skeleton for loading
Conditional Rendering - Rendering based on the conditions
Render - If there is any update of data done via useState, react re-renders that entire component (reconciliation cycle) and diff algo finds the difference and updates that particular element
Working on the typehead feature and Search button
More useEffect (Dependency Array) -> - If no dependency array (optional param in useEffect) -> useEffect is called on render of a component. - If there is an empty dependency Array, useEffect is called on inital render of a component and just once. - If there is a dependency Array, everytime that value is changes, react re-renders components. - We can return a function inside this hook and is called after component is removed from the DOM (similar to unmounting): eg: setInterval() - We cannot use async function in useEffect callback
useState (Best practices) -> - Always call it within the functional components since its a local state variable for the same. - Avoid using it within the if/else condition - for - loops - functions as it would create incosistency
React Router
-
First we define configuration by importring createBrowserRouter();
-
Then we define an array fo path and its respective element as the arguments
-
Here comes RouterProvider will provide config to our application
-
For 404 not found page, we can use a hook called useRouteError to show specific error messages
Children Routes - Routes can have children routes as well as we do not want to replace everything when a route is changed, for eg: Header, footer (visible in all paths)
Outlet - It is like a tunnel; it will be filled with the children according to the path on what page we are. - Used in place of Body element since it is dynamic as per the path - Renders the child route's element, if there is one.
Link - To navigate to the different page (its just replacing on the same page) without reload. - Same as anchor tag but instead of href, here it is to Tip: - Never use anchor tag in react to route to a different page. why? - Because it refreshes the whole page.
Single Page Applications - Only one page with the exchange of components
Types of Routing - Client side routing (Which react uses with no networkc calls) - Server side routing (Network calls based on the page request to be loaded)
Dynamic Routing - define dyanmic routing with ':id'; For eg: path: '/restauarants/:resid', here :resid will be dynamic for each restuarant.
GrpahQL - Queries the data, solves the overfetching of the data useParams - Returns an object with the parameters passed in the URL useNavigate - Returns a function to navigate to a different page useLocation - Returns the current location of the page useRouteError - Returns the error message for the 404 not found page
-
Class method has a piece of class which has render method that returns JSX
-
Passing props to a class based component via constructor super props
-
this.state (reserved keyword) variable which is a big object in React - best place is inside the contrusctor where an instance is created whenever the class component is mounted
-
Updating the state variables (never update the states directly) -> this.setState({})
LifeCycle Methods of React Class based Components
- ComponentDidMount - triggered after component is loaded or rendered/mounted (for one children)
- For parents with multiple children
use case: API Calls since it follows load-> render -> API call -> render
- For parents with multiple children
- ComponentDidMount - triggered after component is loaded or rendered/mounted (for one children)
1. **Render Phase** -> Pure and has no side-effects, maybe paused or aborted by React. (**constructor and render method is called here**)
2. **Commit Phase** -> Can work with DOM, run side effects and schedule updates. Updated in single Batch.
## Mounting Cycle
1. *ComponentDidMount* - called after constructor and render method is done calling.
## Updating Cycle
2. *ComponentDidUpdate* - called after state variable is updated with a new data (eg:API call)
## UnMounting Cycle
3. *ComponentWillUnmount* - called when component is unmounted i.e. removed from the DOM.
Single Responsibility Principle
- Each component should have only one responsibility
Custom Hooks
- Custom hooks are reusable pieces of code that can be used in multiple components.
- They are used to abstract away complex logic and make it reusable.
Optimization
- Code splitting
- Lazy loading
- using lazy function to lazy load components
- eg: const Grocery = lazy(() => import("./components/Grocery"));
- Chunking
- Dynamic bundling
- On Demand loading
- Dyanmic import
Suspense Compoennt - Suspense is a component that allows us to handle loading states in React. - It can be used to display a fallback component while a component is being loaded. - It can be used to display a loading state while a component is being loaded. - It can also be used to handle errors and display an error message.
Styling components in many ways.
1. SASS/SCSS
2. CSS
3. Styled Components
4. Tailwind CSS
5. Material UI
Many more....
##Install Tailwind
- Tailwind css uses postcss behind the scenes to transform CSS with JavaScript.
- Conversion of normal css to tailwind
Higher Order Components
- Takes a component, enhances it and returns a component
- Used to abstract away complex logic and make it reusable
- Created Restaurant promoted label with Restuarant card
- They are pure functions
Pure Functions
- They always return the same output given the same inputs
- They have no side effects
- They are predictable and easy to test
- They are immutable
- Not all higher order functions are pure
React Dev Tools :
- React Dev Tools is a browser extension that allows you to inspect and debug React components in your application Left side - UI layer | Right side - Data Layer
Lifting the Stats up
- When you need to share data between components, lift it up to the parent component.
- This is a good practice because it makes the code more predictable and easier to debug.
Controlled vs Uncontrolled Components
- Controlled Components: The component's state is controlled by the parent component.
- Uncontrolled Components: The component's state is controlled by the component itself.
Props Drilling
- Props drilling is a technique used in React to pass props from a parent component to a child component
- It is used to avoid lifting the state up to the parent component.
React Context
- A global space to keep the data and be accessible for all the components of your app
- Because of the issue in prop drilling down in so many components, react context comes to the picture.
- createContext() is the utility function that helps us create the context.
- useContext() - A hook that is used to access the created context in any component.
- In class based components, to consume a context, we can use UserContext.Consumer (since we do not have any hooks)
- To update a context value and notify all the other components about the update value, we can use UserContext.Provider
Redux Toolkit:
- A predictable state container for JS Apps (not exclusive to react)
- A big JS object kept in a Global centralized place
Slice:
-
A piece of the redux store (Cart data)
-
Writing the data in redux For example -> when we need to update cart items (Add to cart), we should not update it directly instead dispatch an action for the same and calls a function known as reducer (a function that will update the cart)
-
Reading the data from the redux For example -> to read the data and updated cart items count we need a selector (subscribing to the store)
Note: Selector, dispatch is a hook
Steps and info:
- Create a add store (configureStore())
- Add a provider as a wrapper to your main app.
- Create a slice (each slice will have its own reducer) by addind actions and reducer and hence exporting it.
- Add the created slice to your store
- Reducer (one main reducer) can have multiple reducers (cart reducer has multiple reducer functions)
- Old redux -> cannot mutate the state vs New Redux Toolkit -> can mutate the state (internally redux is handling the immutability using immer.js).
- No need to return the state, you can either mutate the state or return the empty state
Few interview questions/tips on Redux:
- Make sure you subscribe to the right portion of the store - otherwise it's a performance loss.
- Make sure you don't dispatch the same action multiple times - otherwise it's a performance loss.
/* Header - Logo - Nav items
Body
- Search
- Restaurant Container
- Restaurant Cards
- Image
- Name of the restaurant
- Rating Star
- Cuisine
- Delivery Timer
Footer
- Copyrights
- Links
- Address
- Contact
*/
// Color theme /** @type {import('tailwindcss').Config} / module.exports = { content: [ "./src//*.{html,js,ts,jsx,tsx}", ], theme: { extend: { colors: { themePurple: '#800080', // Your base purple themePink: '#fde6f3', // Example pink (you can customize this) shadowPink: '#eed1ed' }, }, }, plugins: [], corePlugins: { preflight: true, // Make sure to retain the base styling }, // Add custom utility classes safelist: [ { pattern: /line-clamp/, }, ], }