Join DevzConnect — where devs connect, code, and level up together. Got questions? Stuck on a bug? Or just wanna help others crush it? Jump in and be part of a community that gets it
Welcome back to DevzConnect — where devs connect, code, and level up together. Ready to pick up where you left off? Dive back in, ask questions, share wins, or help others crush their goals!
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
What is the difference between SSR and CSR?
SSR (Server-Side Rendering) and CSR (Client-Side Rendering) are two different approaches to rendering web pages in web applications. Both have their own benefits and drawbacks, and the choice between them depends on the specific requirements of the application. Let's explore the differences betweenRead more
SSR (Server-Side Rendering) and CSR (Client-Side Rendering) are two different approaches to rendering web pages in web applications. Both have their own benefits and drawbacks, and the choice between them depends on the specific requirements of the application. Let’s explore the differences between SSR and CSR:
1. SSR (Server-Side Rendering):
In SSR, the web page is rendered on the server and sent to the client (browser) as a fully formed HTML document.
How it works:
Pros of SSR:
Cons of SSR:
Use Cases for SSR:
2. CSR (Client-Side Rendering):
In CSR, the web page is rendered on the client (browser) using JavaScript. The server sends a minimal HTML page that includes JavaScript code to render the content.
How it works:
Pros of CSR:
Cons of CSR:
Use Cases for CSR:
Key Differences between SSR and CSR:
Hybrid Approach (SSR + CSR):
Many modern React frameworks (e.g., Next.js, Nuxt.js) offer a hybrid approach where pages are rendered on the server for better SEO and faster initial load, but client-side JavaScript takes over for dynamic content and interactivity. This combines the benefits of both SSR and CSR.
Conclusion:
What are compound components?
Compound components in React are a pattern that allows multiple components to work together in a cohesive way while still being reusable. The idea is that you can break down a complex component into smaller, more manageable pieces that each have a specific responsibility, while maintaining control aRead more
Compound components in React are a pattern that allows multiple components to work together in a cohesive way while still being reusable. The idea is that you can break down a complex component into smaller, more manageable pieces that each have a specific responsibility, while maintaining control and communication between them.
In compound components, the child components are able to communicate with the parent component or the sibling components using shared state, context, or props. This allows for better composition and flexibility.
Characteristics of Compound Components:
Example: A
Tabs
Component as a Compound ComponentLet’s look at an example where we create a
Tabs
component using the compound component pattern. In this example, theTabs
,TabList
,Tab
, andTabPanel
components will work together.Step 1: Create the Compound Component
Explanation:
Tabs
Component: This is the parent component. It maintains theselectedIndex
state, which keeps track of which tab is selected. It passes down this state, along with theonTabClick
function, to its children (TabList
,Tab
, andTabPanel
).TabList
Component: This is a container for theTab
components. It receives theselectedIndex
andonTabClick
props and maps over its children (Tab
) to pass them the necessary props, such asisSelected
andonTabClick
.Tab
Component: This represents an individual tab button. It receives theisSelected
prop, which determines whether the tab is active or not, and theonTabClick
function, which handles the tab switching.TabPanel
Component: This is where the content of each tab is displayed. It checks if itsindex
matches theselectedIndex
and renders the content accordingly.Benefits of Compound Components:
Example Use Cases:
Form
,Input
,Select
,SubmitButton
, etc., where theForm
component controls the form submission and validation, while each input handles its own rendering and interaction.ModalHeader
,ModalBody
, andModalFooter
, each of which can be styled and handled separately while still being part of the same modal dialog.Conclusion:
Compound components are a powerful pattern in React that allows for flexible, reusable, and maintainable component structures. By letting parent components control shared state and passing down relevant props to child components, you can create complex UIs that are easy to manage and extend
See lessWhat is the useRef hook?
The useRef hook in React is used to persist values across renders without causing a re-render. It can store a reference to a DOM element, a value, or even a function that doesn't change between renders. It's useful for accessing or modifying a DOM element directly or for keeping track of values thatRead more
The
useRef
hook in React is used to persist values across renders without causing a re-render. It can store a reference to a DOM element, a value, or even a function that doesn’t change between renders. It’s useful for accessing or modifying a DOM element directly or for keeping track of values that should not trigger a re-render when they change.Syntax:
const myRef = useRef(initialValue);
initialValue
: The initial value you want to store in theuseRef
object (optional). For DOM elements, it’s usuallynull
, and for general values, it can be any value like0
, an empty string, or an object.myRef.current
: Thecurrent
property of the object returned byuseRef
will store the actual value you’re referring to.Key Uses of
useRef
:useRef
to reference and interact with a DOM element directly without needing to usedocument.querySelector()
or other DOM methods.useRef
that doesn’t change between renders and can be accessed later.Example 1: Accessing DOM Elements with
useRef
In this example, we’ll focus on using
useRef
to access a DOM element (like an input field) directly and manipulate it.Explanation:
inputRef
is initialized usinguseRef(null)
because it’s going to store a reference to the DOM element (the input field).inputRef
to theref
attribute of the<input>
element.handleFocus
function accessesinputRef.current
(the DOM element) and callsfocus()
on it, causing the input field to gain focus.Example 2: Storing Mutable Values Without Causing Re-Renders
Here’s how you can use
useRef
to persist a value without triggering a re-render:Explanation:
prevCountRef
stores the previous count value usinguseRef()
.useEffect
, we updateprevCountRef.current
to the currentcount
whenever it changes.prevCountRef.current
doesn’t trigger a re-render, so the UI will still reflect the latest count but will show the previous value from theuseRef
object.Key Points About
useRef
:Doesn’t trigger re-renders: Updating the
.current
property of a ref does not cause the component to re-render. This is why it’s useful for storing mutable values that do not need to affect the UI directly.DOM references: When you pass a
ref
to a DOM element,useRef
will hold a reference to that element, allowing you to directly interact with the DOM.Persisted values: You can store values (like timers, previous states, etc.) in
useRef
that persist across renders but don’t cause re-renders when updated.Example 3: Storing a Timer ID
Here’s an example where
useRef
is used to store a timer ID so that you can clear it when needed:Explanation:
timerRef
stores the ID of the timer returned bysetInterval
.useEffect
to start the timer when the component mounts and clean it up when the component unmounts (to avoid memory leaks).setState
only to update theseconds
value.Conclusion:
The
See lessuseRef
hook is a versatile tool in React for managing references to DOM elements, storing mutable values across renders, and preventing unnecessary re-renders. It is essential for cases where you need to directly manipulate the DOM, store previous values, or hold on to values that don’t need to trigger a UI update when changed.What is the useReducer hook?
The useReducer hook in React is an alternative to useState that is used to manage more complex state logic in a component. It's particularly useful when the state you want to manage has multiple sub-values or when the state transitions are more complex and depend on the previous state. useReducer isRead more
The
useReducer
hook in React is an alternative touseState
that is used to manage more complex state logic in a component. It’s particularly useful when the state you want to manage has multiple sub-values or when the state transitions are more complex and depend on the previous state.useReducer
is similar touseState
, but instead of directly updating the state with a new value, it uses a reducer function to determine how the state should change based on an action.Syntax:
const [state, dispatch] = useReducer(reducer, initialState);
reducer
: A function that specifies how the state should change based on an action. It takes two arguments: the current state and the action, and returns the new state.initialState
: The initial state value.state
: The current state after applying the reducer function.dispatch
: A function used to send actions to the reducer. It’s typically used to trigger state changes.When to use
useReducer
:Example Usage:
Simple Counter with
useReducer
:Explanation:
Reducer function: The
reducer
function describes how the state should change based on the action type. It checks the action type (e.g.,'increment'
or'decrement'
) and returns the updated state.useReducer
: This hook initializes the state ({ count: 0 }
), and thedispatch
function allows triggering actions (like incrementing or decrementing the count).Dispatching actions: When the user clicks the “Increment” or “Decrement” buttons, the
dispatch
function is called with an action object. Thereducer
function then processes the action and returns a new state.Example with Multiple State Variables:
You can also use
useReducer
when managing multiple pieces of state or more complex state logic.Explanation:
In this example,
useReducer
manages two pieces of state (name
andage
) with a single reducer function. Thedispatch
function is used to update the state based on different actions (setName
andsetAge
).Key Points:
useReducer
vsuseState
: UseuseReducer
when you have more complex state transitions or need to handle multiple sub-values in your state. If the state is simple (just a single value or boolean),useState
is typically more concise.Reducer function: The reducer handles all state changes and returns the updated state based on the received action.
Dispatching actions: You dispatch actions by calling
dispatch()
and passing an action object, typically containing atype
and optionally apayload
.Benefits of
useReducer
:Conclusion:
See lessuseReducer
is a powerful hook for managing complex state in React components. It’s often used when state changes depend on a variety of actions or when multiple values need to be updated simultaneously. It provides a structured and predictable way to manage state, similar to state management libraries like Redux but within the context of a single component.What are concurrent features in React 18?
React 18 introduces several Concurrent Features that allow React to work in a more efficient and responsive way by rendering in the background, prioritizing updates, and keeping the UI interactive. These features are designed to make React apps feel faster and more fluid, especially when dealing witRead more
React 18 introduces several Concurrent Features that allow React to work in a more efficient and responsive way by rendering in the background, prioritizing updates, and keeping the UI interactive. These features are designed to make React apps feel faster and more fluid, especially when dealing with complex and resource-intensive UIs.
Key Concurrent Features in React 18:
Concurrent Rendering (Concurrent Mode):
ReactDOM.createRoot()
.const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Suspense for Data Fetching:
Suspense
to wrap components that depend on asynchronous data. While the data is being fetched, a fallback (like a loading spinner) is shown, and once the data is available, the component renders.Automatic Batching of Updates:
Transition API:
startTransition
function to wrap state updates that you consider non-urgent. React will prioritize urgent updates (like typing or clicking) over transitions.Concurrent Features in
useDeferredValue
:useDeferredValue
hook helps delay rendering of certain components until more important updates have been processed. This is especially useful in situations like search input or filters, where the UI should remain responsive and not update too quickly while typing.useDeferredValue
to allow React to defer its update and prioritize more urgent UI updates (like typing). ThedeferredValue
will be updated at a later time, preventing unnecessary re-renders.Summary of Concurrent Features:
How to Enable Concurrent Features:
In React 18, Concurrent Mode and other concurrent features are opt-in and require using
ReactDOM.createRoot()
to create a root, as opposed to the olderReactDOM.render()
method.const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Conclusion:
React 18’s concurrent features allow you to build more performant and responsive applications by enabling fine-grained control over updates. These features make it easier to manage complex UIs and asynchronous tasks, improving the user experience and app performance.
See lessWhat is the useImperativeHandle hook?
The useImperativeHandle hook in React is used to customize the instance value that is exposed when using ref with a functional component. It is often used to expose specific methods or properties to the parent component via ref, rather than the entire instance of the component. By default, React expRead more
The
useImperativeHandle
hook in React is used to customize the instance value that is exposed when usingref
with a functional component. It is often used to expose specific methods or properties to the parent component viaref
, rather than the entire instance of the component.By default, React exposes the DOM node (or component instance) when using
ref
, but sometimes you want to expose only certain methods or properties to the parent.useImperativeHandle
allows you to do this by modifying the value returned byref
.Syntax:
useImperativeHandle(ref, createHandle, [dependencies]);
ref
: Theref
object that is passed down from the parent.createHandle
: A function that returns an object with methods or properties to expose to the parent.dependencies
: An optional array of dependencies to re-run thecreateHandle
function.Example Usage:
Let’s say you have a
CustomInput
component, and you want to allow the parent component to focus on the input field using aref
.How It Works:
CustomInput
Component:forwardRef
to forward theref
to theCustomInput
component.CustomInput
, we use theuseRef
hook to reference the actualinput
element.useImperativeHandle
to expose a customfocus
andclear
method to the parent component, so when the parent accesses theref
, it can call these methods directly.ParentComponent
:ref
usinguseRef()
and pass it down toCustomInput
.focus
andclear
on theref
to manipulate the input field without directly accessing the DOM node.Key Points:
useImperativeHandle
is used to control the value that is exposed to the parent when usingref
in functional components.forwardRef
to forward aref
to the child component.When to use it?
In most cases, you’ll rely on the default behavior of
See lessref
, butuseImperativeHandle
is helpful when you want to have more fine-grained control over the exposedref
behavior.What is React Fiber?
React Fiber is a core part of React’s internal architecture, and as a developer, you don’t need to implement or directly interact with it. It works behind the scenes and enhances the rendering process automatically. What does this mean for developers? You don’t need to worry about React Fiber explicRead more
How do you manage global state in React?
Managing global state in React means managing data that needs to be accessible throughout different parts of your application, such as user authentication info, theme settings, or a shopping cart. React provides several ways to handle global state, and I'll explain a few beginner-friendly approachesRead more
Managing global state in React means managing data that needs to be accessible throughout different parts of your application, such as user authentication info, theme settings, or a shopping cart. React provides several ways to handle global state, and I’ll explain a few beginner-friendly approaches.
1. Using React’s Built-in State (Props and Context)
For simple use cases where you need to share state across components, React’s built-in state management (
useState
anduseContext
) can be enough.Using
useState
and PropsWhen components are related (e.g., parent-child), you can pass the state from a parent component down to child components through props.
Example:
In this example:
useState
is used to manage thecount
state.count
state and thesetCount
function are passed down as props to theChildComponent
.ChildComponent
is clicked, it updates the state in the parentApp
component.Using
useContext
for Sharing State Across ComponentsIf you need to share state between components that are not directly related (e.g., sibling components or deeply nested components), you can use React Context.
Example
In this example:
CountContext
) is created to store the global state.CountContext.Provider
is used to wrap the components that need access to the global state (here, the entireApp
).useContext(CountContext)
is used inside any component (likeChildComponent
) to access the global state (count
) and the function to update it (setCount
).2. Using External Libraries (Redux or Zustand)
When your application grows larger and the state management becomes more complex (for example, if you have many components that need to access or update the state), you might need more advanced state management tools like Redux or Zustand.
Using Redux (A More Advanced Approach)
Redux is a widely-used library for managing global state, but it can be complex for beginners. Here’s a quick overview:
Here’s a very simplified example of Redux:
Install Redux and React-Redux:
npm install redux react-redux
Create a Redux Store:
Connect Redux to React:
In this example:
count
) is managed in the Redux store.useSelector
is used to access the state, anduseDispatch
is used to dispatch actions that update the state.3. When to Use Context vs Redux
Use React Context when:
Use Redux when:
Summary:
useState
: Best for simple, local state management.What is useMemo?
n React, useMemo is a hook that helps optimize performance by memoizing the result of an expensive computation, preventing unnecessary recalculations on every render. Essentially, it "remembers" the result of a computation and only recalculates it if one of the dependencies has changed. Syntax: consRead more
n React,
useMemo
is a hook that helps optimize performance by memoizing the result of an expensive computation, preventing unnecessary recalculations on every render. Essentially, it “remembers” the result of a computation and only recalculates it if one of the dependencies has changed.Syntax:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
computeExpensiveValue(a, b)
: This is the function or computation you want to memoize.[a, b]
: These are the dependencies that trigger a recomputation when their values change. If none of the dependencies change between renders, the memoized value is used instead of recalculating.When to Use
useMemo
?useMemo
is useful when:Example 1: Avoiding Recalculations
Here:
expensiveComputation
will only run when eithera
orb
changes. If both are the same between renders, React will return the memoized value instead of recalculating it.useMemo
,expensiveComputation
would be called on every render, which could be inefficient.Example 2: Optimizing a List Filtering
In this example:
filter
state.useMemo
ensures that thefilter
operation is only performed when the filter input changes. WithoutuseMemo
, the filtering would be repeated on every render, even if the filter value hasn’t changed.Important Notes:
useCallback
instead.useMemo
can improve performance, it introduces some overhead. It’s typically used for expensive computations. In most cases, React is efficient enough, souseMemo
should be used only when needed.Summary:
useMemo
is used to memoize expensive calculations or operations, ensuring they are only recomputed when necessary (i.e., when dependencies change).What is Redux and how does it work with React?
Redux is a state management library for JavaScript applications, commonly used with React to manage and centralize the state of an application. It provides a predictable way to manage the state across different components and allows easy sharing of state between them. Here's how it works: Core ConceRead more
Redux is a state management library for JavaScript applications, commonly used with React to manage and centralize the state of an application. It provides a predictable way to manage the state across different components and allows easy sharing of state between them. Here’s how it works:
Core Concepts of Redux
Store: The central repository where all the application’s state is stored. It’s like a big object that holds the entire state of your app.
Actions: These are plain JavaScript objects that describe what happened. They are the only way to send data to the store. Every action must have a
type
field (which is a string) that indicates the action’s kind.Example:
Reducers: These are pure functions that specify how the state should change in response to an action. A reducer takes the current state and an action, and returns a new state.
Example:
Dispatch: Dispatch is the method that sends actions to the store to update the state.
Example:
store.dispatch(addItemAction);
Selectors: Functions that allow you to extract specific pieces of data from the store.
Redux Flow with React
Install Redux and React-Redux First, install Redux and React-Redux (which connects Redux to React).
npm install redux react-redux
Create Redux Store
Use
createStore
to create a Redux store by passing a reducer that handles how the state changes.Example:
import { createStore } from 'redux';
const store = createStore(itemsReducer);import { itemsReducer } from './reducers';
Connect Redux to React
Provider
fromreact-redux
, passing the store as a prop.Using Redux in React Components
Example of using Redux in a React component:
In this example:
useSelector
is used to access theitems
array from the store.useDispatch
is used to send the action to the store to add a new item.How Redux Solves Problems in React
Centralized State: With Redux, you can manage your app’s state in one place. Instead of passing props between deeply nested components, you can access the state directly from anywhere.
Predictability: Since reducers are pure functions, they take in an action and return a new state. This makes it easier to understand and debug state changes.
Unidirectional Data Flow: Data in Redux flows in one direction:
DevTools: Redux has powerful developer tools that allow you to inspect actions, state changes, and even time travel through the state history.
When to Use Redux
While Redux is a powerful tool for managing global state, it’s not always necessary. It’s most beneficial when:
If your app has simple state or small state requirements, React’s built-in state management (with
useState
anduseReducer
) might be sufficient, and Redux might be overkill.Summary
Provider
component to pass the store anduseSelector
anduseDispatch
hooks to interact with the store in React components.