Add react questions (#4492)

* Add more questions

* wip: add lazy, conditional questions

* wip: Add RSC questions

* wip: add component's lifecycle

* wip: add dependency array question

* wip: add comment and state

* chore: add more questions

* wip: add list question

* wip: add directive questions

* fix: conventions and examples

* wip: add custom hook question

* wip: add hydration question

* wip: add error boundary example

* wip: add strict mode question

* wip: investigating slow react app

* Update src/data/question-groups/react/react.md

* Update src/data/question-groups/react/react.md

---------

Co-authored-by: Kamran Ahmed <kamranahmed.se@gmail.com>
pull/4500/head
Arik Chakma 1 year ago committed by GitHub
parent aa6d48b775
commit edcf0e683d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      src/data/question-groups/react/content/component-lifecycle.md
  2. 51
      src/data/question-groups/react/content/custom-hook.md
  3. 37
      src/data/question-groups/react/content/error-boundaries.md
  4. 9
      src/data/question-groups/react/content/flush-sync.md
  5. 33
      src/data/question-groups/react/content/investigate-slow-app.md
  6. 39
      src/data/question-groups/react/content/lazy-loading.md
  7. 17
      src/data/question-groups/react/content/render-list.md
  8. 19
      src/data/question-groups/react/content/strict-mode.md
  9. 23
      src/data/question-groups/react/content/suspense.md
  10. 67
      src/data/question-groups/react/content/use-transition.md
  11. 5
      src/data/question-groups/react/content/virtual-dom.md
  12. 126
      src/data/question-groups/react/react.md

@ -0,0 +1,32 @@
In React functional components, lifecycle-like behaviors are achieved using hooks:
## Mounting and Unmounting
Utilizing the useEffect hook with an empty dependency array ([]) ensures the hook runs after the component mounts to the DOM.
```js
useEffect(() => {
// do something after component mounts
return () => {
// do something before component unmounts
};
}, []);
```
The cleanup function returned within the useEffect callback offers a mechanism for handling tasks when the component is about to **unmount**.
## Updates
The useEffect hook, when invoked without a dependency array or with specific dependencies, executes after every render or when specified prop/state changes are detected.
```js
useEffect(() => {
// do something after every render
});
```
```js
useEffect(() => {
// do something after specific prop/state changes
}, [state1, state2]);
```

@ -0,0 +1,51 @@
**Custom hooks** are a mechanism for code reuse in React and allow you to extract component logic into reusable functions. Custom hooks can be used to share logic between components or to abstract away complex logic to make components more readable.
Let's look at an example of a custom hook that return network status information:
## Creating a Custom hook
Custom hooks are named with the prefix `use` and can call other hooks if needed. They can also accept arguments and return values.
```js
import { useState, useEffect } from 'react';
function useNetworkStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
function handleOnline() {
setIsOnline(true);
}
function handleOffline() {
setIsOnline(false);
}
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
};
}, []);
return isOnline;
}
```
The custom hook above uses the `useState` and `useEffect` hooks to track the network status of the browser. It returns a boolean value that indicates whether the browser is online or offline.
## Using a Custom hook
```js
function NetworkStatus() {
const isOnline = useNetworkStatus();
return (
<div>
<p>You are {isOnline ? 'online' : 'offline'}.</p>
</div>
);
}
```

@ -0,0 +1,37 @@
Error boundaries are special React components that catch JavaScript errors during rendering, in lifecycle methods, and during the constructor of whole tree below them. They are used to handle errors gracefully by displaying a fallback UI and preventing the entire application from crashing due to unhandled errors.
You can use [react-error-boundary](https://npm.im/react-error-boundary) package to create error boundaries in your application. It provides a `ErrorBoundary` component that you can wrap around any component that might throw an error. The `ErrorBoundary` component takes a `FallbackComponent` prop that is used to render a fallback UI when an error occurs.
## Capturing Errors
```js
import { ErrorBoundary } from 'react-error-boundary';
import { FetchData } from './FetchData';
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<p>Something went wrong:</p>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
export function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<FetchData />
</ErrorBoundary>
);
}
```
This `FetchData` component will throw an error when it is rendered, and the `ErrorBoundary` component will catch the error and display the `ErrorFallback` component.
```js
export function FetchData() {
throw new Error('Error fetching data');
return <p>This will never render</p>;
}
```

@ -0,0 +1,9 @@
The `flushSync` function in React is used to flush updates synchronously. It schedules updates to be performed inside a high-priority task, ensuring that the updates are executed immediately and synchronously before returning control to the caller.
```js
import { flushSync } from 'react-dom';
flushSync(callback);
```
This is useful in situations where you need the DOM to be updated immediately, such as for measurements or to ensure synchronous rendering. However, excessive use of `flushSync` can lead to degraded performance, so it should be used judiciously.

@ -0,0 +1,33 @@
There are many reasons why an app might be slow. It could be due to a slow network, a slow backend, or a slow client. It could also be due to a memory leak, unnecessary re-renders, or large bundle sizes.
Here are some tips to help you investigate and fix performance issues:
## Use the React DevTools Profiler
The React DevTools Profiler helps you visualize how components render and identify costly renderings. It can also help you identify unnecessary re-renders.
## Check for Unnecessary Renders
Ensure that components don't render more often than needed. Be clear about the `useEffect` dependencies and avoid creating new objects or arrays every render, as these can trigger unnecessary child component renders. Tools like [why-did-you-render](https://npm.im/@welldone-software/why-did-you-render) can help spot unnecessary re-renders.
## Analyze Bundle Size
Use your production build to analyze your bundle size. Tools like [webpack-bundle-analyzer](https://npm.im/webpack-bundle-analyzer) or [source-map-explorer](https://npm.im/source-map-explorer) can help you see if large libraries or unused code is slowing down the initial load.
## Optimize Images & Assets
Ensure images are appropriately sized and use modern formats. Also, consider using CDNs for assets that don't change often.
## Lazy Load Components
Use `lazy()` and dynamic imports to split your bundle and load components only when they're needed. This can help reduce the initial load time.
## Check Network Requests
Slow API calls or fetching large amounts of data can affect performance. Optimize your backend, paginate data, or cache results. You can also use tools like [@tanstack/react-query](https://npm.im/@tanstack/react-query) or [swr](https://npm.im/swr) to help manage data fetching and caching.
## Use Production Build for Testing
Ensure you're testing the performance on a production build, as development builds are often slower due to extra checks and logs.
Regularly profiling and monitoring your app can help you spot and fix performance issues before they become significant problems. You can use tools like [Lighthouse](https://developers.google.com/web/tools/lighthouse) or [Calibre](https://calibreapp.com) to monitor your app's performance over time.

@ -0,0 +1,39 @@
You can use React's `lazy()` function in conjunction with dynamic `import()` to lazily load a component. This is often combined with `Suspense` to display fallback content while the component is being loaded.
```js
// The component has to be exported as a default export
export default function RoadmapRender() {
return <h1>This is a lazily-loaded component!</h1>;
}
```
```js
import { lazy, Suspense } from 'react';
const LazyRoadmapRender = lazy(() => delay(import('./RoadmapRender')));
export function App() {
const [showRoadmapRender, setShowRoadmapRender] = useState(false);
return (
<>
<button onClick={() => setShowRoadmapRender(true)}>
Show RoadmapRender
</button>
{showRoadmapRender && (
<Suspense fallback={<div>Loading...</div>}>
<LazyRoadmapRender />
</Suspense>
)}
</>
);
}
// Helper function to simulate a 2 seconds delay
function delay(promise) {
return new Promise((resolve) => setTimeout(resolve, 2000)).then(
() => promise
);
}
```
The `RoadmapRender` component is lazily loaded and rendered inside the `Suspense` component. While the component is being loaded, the `Suspense` component will display the fallback content.

@ -0,0 +1,17 @@
In React, you can render a list by using the JavaScript `map` function to iterate over an array of items and return a JSX element for each item. It's important to provide a unique `key` prop to each element in the list for React's diffing algorithm to function efficiently during re-renders. Here's a basic example:
```javascript
const items = ['Apple', 'Banana', 'Cherry'];
function FruitList() {
return (
<ul>
{items.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
);
}
```
> Note: While using the index as a key can work in some cases, it's generally not recommended for dynamic lists where items can be added, removed, or reordered.

@ -0,0 +1,19 @@
Strict Mode is a tool in React for highlighting potential problems in an application. By wrapping a component tree with `StrictMode`, React will activate additional checks and warnings for its descendants. This doesn't affect the production build but provides insights during development.
```js
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);
```
In Strict Mode, React does a few extra things during development:
1. It renders components twice to catch bugs caused by impure rendering.
2. It runs side-effects (like data fetching) twice to find mistakes in them caused by missing effect cleanup.
3. It checks if deprecated APIs are used, and logs a warning message to the console if so.

@ -0,0 +1,23 @@
Suspense is a component in React that lets you specify the fallback content to display while waiting for a component to load. It is used in conjunction with `lazy()` to lazily load components.
```js
import { lazy, Suspense } from 'react';
const LazyRoadmapRender = lazy(() => import('./RoadmapRender'));
export function App() {
const [show, setShow] = useState(false);
return (
<>
<button onClick={() => setShow(true)}>Show</button>
{show && (
<Suspense fallback={<div>Loading...</div>}>
<LazyRoadmapRender />
</Suspense>
)}
</>
);
}
```
Until the `RoadmapRender` component is loaded, the `Suspense` component will display the `Loading...` fallback content.

@ -0,0 +1,67 @@
`useTransition` hook allows you to mark certain updates as **transitions** so they can be deprioritized, allowing other, more urgent updates to be processed first. This ensures that the UI remains responsive during updates that might take some time.
```js
import { useTransition, useState } from 'react';
import { Posts } from './Posts';
import { Home } from './Home';
import { Contact } from './Contact';
export function App() {
const [isPending, startTransition] = useTransition();
const [page, setPage] = useState('home');
function changePage(newPage: string) {
startTransition(() => {
setPage(newPage);
});
}
return (
<>
<button onClick={() => changePage('home')}>Home</button>
<button onClick={() => changePage('posts')}>Posts</button>
<button onClick={() => changePage('contact')}>Contact</button>
<hr />
{isPending && <div>Loading...</div>}
{page === 'home' && <Home />}
{page === 'posts' && <Posts />}
{page === 'contact' && <Contact />}
</>
);
}
```
```js
export function Home() {
return <div>Home</div>;
}
```
```js
export function Contact() {
return <div>Contact</div>;
}
```
Posts component is artificially delayed by 500ms to emulate extremely slow code.
```js
export function Posts() {
const items = [];
for (let i = 0; i < 500; i++) {
items.push(<SlowPost key={i} />);
}
return <ul>{items}</ul>;
}
function SlowPost() {
const startTime = performance.now();
while (performance.now() - startTime < 1) {
// Do nothing for 1 ms per item to emulate extremely slow code
}
return <li>Post</li>;
}
```
Now when you click on the `Posts` button, you'll notice that the UI remains responsive and you can still switch to other pages while the posts are loading. Try removing the `startTransition` wrapper around `setPage` in `changePage` to see the difference.

@ -0,0 +1,5 @@
Virtual DOM works in this steps:
1. Whenever any underlying data changes, new virtual DOM representation will be created.
2. Then the difference between the previous DOM representation and the new one is calculated.
3. Once the calculations are done, the real DOM will be updated with only the things that have actually changed.

@ -169,22 +169,140 @@ questions:
- 'Performance'
- 'Intermediate'
- question: Explain the concept of error boundaries in React.
answer: |
Error boundaries are special React components that catch JavaScript errors during rendering, in lifecycle methods, and during the constructor of whole tree below them. They are used to handle errors gracefully by displaying a fallback UI and preventing the entire application from crashing due to unhandled errors.
answer: error-boundaries.md
topics:
- 'Core'
- 'Advanced'
- question: What are fragments in React?
answer: |
React doesn't allow returning multiple elements from a component. You can use fragments to return multiple elements.
Fragments in React allow for a group of elements to be returned from a component's render method without adding an extra node to the DOM. They are useful when you want to return multiple elements without wrapping them in a parent container.
topics:
- 'Core'
- 'Beginner'
- question: What is `createPortal`?
- question: What are portals in React?
answer: create-portal.md
topics:
- 'Core'
- 'Intermediate'
- question: What is Concurrent React (Concurrent Mode)?
answer: |
Concurrent React, previously referred to as Concurrent Mode, is a set of new features in React that allows React to interrupt the rendering process to consider more urgent tasks, making it possible for React to be more responsive to user input and produce smoother user experiences. It lets React keep the UI responsive while rendering large component trees by splitting the rendering work into smaller chunks and spreading it over multiple frames.
topics:
- 'Performance'
- 'Intermediate'
- question: What is the `useTransition` hook?
answer: use-transition.md
topics:
- 'Performance'
- 'Advanced'
- question: What is the purpose of `flushSync` in React?
answer: flush-sync.md
topics:
- 'Core'
- 'Advanced'
- question: How to render React components as static HTML string?
answer: |
The `renderToString` function in React is part of the `react-dom/server` package and is used to render React components on the server-side to a static HTML string. It is commonly used for server-side rendering (SSR) in React.
topics:
- 'SSR'
- 'Intermediate'
- question: What are Server Components in React?
answer: |
Server Components in allow developers to write components that render on the server instead of the client. Unlike traditional components, Server Components do not have a client-side runtime, meaning they result in a smaller bundle size and faster loads. They can seamlessly integrate with client components and can fetch data directly from the backend without the need for an API layer. This enables developers to build rich, interactive apps with less client-side code, improving performance and developer experience.
topics:
- 'SSR'
- 'Intermediate'
- question: How to lazy load components in React?
answer: lazy-loading.md
topics:
- 'Performance'
- 'Intermediate'
- question: What is `Suspense` in React?
answer: suspense.md
topics:
- 'UX'
- 'Intermediate'
- question: How React Virtual DOM works?
answer: virtual-dom.md
topics:
- 'Core'
- 'Intermediate'
- question: How do Server Components differ from Client Components?
answer: Server Components are rendered on the server and do not require client-side JavaScript for rendering. While Server Components and Client components can coexist in the same app, Server Components can import and render Client components.
topics:
- 'SSR'
- 'Beginner'
- question: How do React Server Components handle data fetching?
answer: Server Components can directly access backend resources, databases, or filesystems to fetch data during rendering, eliminating the need for a separate API layer for data fetching.
topics:
- 'SSR'
- 'Beginner'
- question: What's the component's lifecycle in React?
answer: component-lifecycle.md
topics:
- 'Core'
- 'Beginner'
- question: How to write a comment in React?
answer: |
You can write a comment in JSX by wrapping it in curly braces and using JavaScript's multi-line comment syntax.
```js
{/* This is a comment */}
```
topics:
- 'Core'
- 'Beginner'
- question: What is the difference between stateful and stateless components?
answer: |
The main difference between stateful and stateless components is one has state and the other doesn't. Stateful components keep track of changes to their state and re-render themselves when the state changes. Stateless components, on the other hand, render whatever is passed to them via `props` or always render the same thing.
topics:
- 'Core'
- 'Beginner'
- question: Why you shouldn't use `index` as a key in React lists and iterators?
answer: Using `index` as a key can negatively impact performance and may cause issues with the component state. When the list items change due to additions, deletions, or reordering, using indexes can lead to unnecessary re-renders or even incorrect UI updates. React uses keys to identify elements in the list, and if the key is just an index, it might reuse component instances and state inappropriately. Especially in cases where the list is dynamic or items can be reordered, it's recommended to use unique and stable identifiers as keys to ensure consistent behavior.
topics:
- 'Performance'
- 'Beginner'
- question: What is the naming convention for React components?
answer: In React, the naming convention for components is to use PascalCase, meaning the first letter of each word in the component's name should be capitalized. For example, `UserProfile`, `SidebarItem`, or `NavigationMenu`. This convention differentiates custom React components from regular HTML tags in JSX, as React treats elements starting with a lowercase letter as DOM tags and those starting with a capital letter as custom components.
topics:
- 'Core'
- 'Beginner'
- question: How to render a list in React?
answer: render-list.md
topics:
- 'Core'
- 'Beginner'
- question: What are `use client` and `use server` directives?
answer: The `use client` directive marks source files whose components are intended to execute only on the client. Conversely, `use server` marks server-side functions that can be invoked from client-side code.
topics:
- 'SSR'
- 'Intermediate'
- question: Can you use hooks in Server Components?
answer: No, hooks are not supported in Server Components. Hooks are a client-side feature and are not supported in Server Components. However, you can use hooks in client components and import them into Server Components.
topics:
- 'SSR'
- 'Intermediate'
- question: How to create a Custom hook in React?
answer: custom-hook.md
topics:
- 'Core'
- 'Intermediate'
- question: What is Hydration in React?
answer: |
Hydration is the process of using client-side JavaScript to add interactivity to the markup generated by the server. When you use server-side rendering, the server returns a static HTML representation of the component tree. Once this reaches the browser, in order to make it interactive, React "hydrates" the static content, turning it into a fully interactive application.
topics:
- 'SSR'
- 'Intermediate'
- question: What is Strict Mode in React and why is it useful?
answer: strict-mode.md
topics:
- 'Debugging'
- 'Intermediate'
- question: How do you investigate a slow React app and identify performance bottlenecks?
answer: investigate-slow-app.md
topics:
- 'Performance'
- 'Intermediate'
---

Loading…
Cancel
Save