Mastering React: In-Depth Interview Questions with Detailed Explanations and Code Examples
General Questions
What is React and how does it work?
Answer: React is a JavaScript library for building user interfaces, primarily for single-page applications. It allows developers to create large web applications that can update and render efficiently in response to data changes. React works by creating a virtual DOM, which is a lightweight copy of the actual DOM. When the state of an object changes, React updates the virtual DOM first, then it compares the virtual DOM with a snapshot of the previous virtual DOM (a process called "reconciliation"), and finally, it updates the actual DOM with the minimal number of changes.
Use Case: Use React to build interactive UIs and handle the view layer for web and mobile apps.
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } export default Counter;
Explain the difference between state and props in React.
Answer: State and props are both plain JavaScript objects in React. The difference lies in their purpose and who manages them.
State: Managed within the component (local state). It is mutable and can change over time, typically in response to user actions.
Props: Short for properties, props are read-only and passed from parent to child components. They are used to pass data and event handlers down to child components.
Use Case: Use state for dynamic data that changes over time and props for passing static values or callbacks to child components.
function ChildComponent({ message }) { return <p>{message}</p>; } function ParentComponent() { const [message, setMessage] = useState('Hello, World!'); return ( <div> <ChildComponent message={message} /> <button onClick={() => setMessage('Hello, React!')}>Change Message</button> </div> ); } export default ParentComponent;
What is JSX and why is it used in React?
Answer: JSX stands for JavaScript XML. It is a syntax extension for JavaScript that looks similar to HTML or XML. JSX makes it easier to write and add HTML in React, making the code more readable and expressive. Under the hood, JSX is transformed into React.createElement() calls, which return JavaScript objects called “React elements”.
Use Case: Use JSX to write components in a declarative way, combining UI layout and logic.
const element = <h1>Hello, world!</h1>; // Transformed to: const element = React.createElement('h1', null, 'Hello, world!');
How does the component lifecycle work in React?
Answer: React components go through a lifecycle of events from their creation to their destruction. The lifecycle consists of three main phases:
Mounting: When the component is being inserted into the DOM.
Updating: When the component is being re-rendered as a result of changes to its props or state.
Unmounting: When the component is being removed from the DOM.
Lifecycle Methods: componentDidMount, componentDidUpdate, and componentWillUnmount are examples of lifecycle methods used to perform operations at specific stages.
Use Case: Use lifecycle methods to perform side effects such as fetching data, subscribing to events, or cleaning up resources.
class MyComponent extends React.Component { componentDidMount() { console.log('Component mounted'); } componentDidUpdate(prevProps, prevState) { console.log('Component updated'); } componentWillUnmount() { console.log('Component will unmount'); } render() { return <div>Lifecycle Methods</div>; } }
What are hooks in React and why are they used?
Answer: Hooks are functions that let you "hook into" React state and lifecycle features from function components. They were introduced in React 16.8 to allow the use of state and other React features without writing a class.
Common Hooks: useState, useEffect, useContext, useReducer.
Use Case: Use hooks to manage state and side effects in functional components, enabling cleaner and more concise code.
import React, { useState, useEffect } from 'react'; function Timer() { const [count, setCount] = useState(0); useEffect(() => { const interval = setInterval(() => { setCount(count => count + 1); }, 1000); return () => clearInterval(interval); }, []); return <div>{count}</div>; } export default Timer;
Advanced React Questions
Explain the Context API in React.
Answer: The Context API provides a way to pass data through the component tree without having to pass props down manually at every level. It is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
Use Case: Use the Context API to avoid prop drilling and manage global state or settings that need to be accessed by many components.
const ThemeContext = React.createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar() { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const theme = React.useContext(ThemeContext); return <button className={theme}>Themed Button</button>; }
What is Redux and how is it used in React applications?
Answer: Redux is a predictable state management library for JavaScript applications. It helps you manage the state of your application in a single, centralized store. Redux works by defining actions that describe changes, reducers that handle actions and update the state, and a store that holds the application state.
Use Case: Use Redux for managing complex state logic in large applications, especially when the state needs to be shared across multiple components or persisted.
import { createStore } from 'redux'; // Action const increment = () => ({ type: 'INCREMENT' }); // Reducer const counter = (state = 0, action) => { switch (action.type) { case 'INCREMENT': return state + 1; default: return state; } }; // Store const store = createStore(counter); // Usage store.dispatch(increment()); console.log(store.getState()); // 1
How do you optimize performance in a React application?
Answer: Performance optimization in React can be achieved through various techniques:
Memoization with React.memo: Prevents unnecessary re-renders of functional components.
useMemo and useCallback: Memoizes expensive calculations and functions.
Code splitting: Lazily load components to reduce initial load time.
Lazy loading: Load components only when they are needed using React.lazy and Suspense.
React Profiler: Identify performance bottlenecks in components.
Use Case: Optimize performance to ensure a smooth user experience, especially in applications with complex UIs and large data sets.
import React, { memo } from 'react'; const ExpensiveComponent = memo(({ data }) => { // Perform expensive calculation return <div>{data}</div>; }); function App() { const [data, setData] = useState('Hello'); return <ExpensiveComponent data={data} />; } export default App;
What are React fragments and why are they used?
Answer: React fragments allow you to group multiple elements without adding extra nodes to the DOM. This is useful for returning multiple elements from a component without wrapping them in a parent element like a div.
Use Case: Use React fragments to avoid unnecessary wrapping elements that can affect the DOM structure and CSS styling.
function List() { return ( <React.Fragment> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </React.Fragment> ); } export default List;
How do you handle forms in React?
Answer: Forms in React can be handled using controlled or uncontrolled components.
Controlled Components: Form data is handled by React state. The input value is updated via React state, and every state change is reflected in the input.
Uncontrolled Components: Form data is handled by the DOM itself. Refs are used to access the form values.
Use Case: Use controlled components for managing form data in React state and uncontrolled components when you need to interact with the DOM directly.
// Controlled Component function Controlled
Form() {
const [value, setValue] = useState('');
const handleChange = (e) => {
setValue(e.target.value);
};
return (
<form>
<input type="text" value={value} onChange={handleChange} />
</form>
);
}
// Uncontrolled Component
function UncontrolledForm() {
const inputRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
console.log(inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<button type="submit">Submit</button>
</form>
);
}
```
React with .NET Core Integration
How do you set up a project with both React and .NET Core?
Answer: A project with React and .NET Core can be set up using the React template provided by the .NET Core CLI or by manually creating a React app and configuring it to communicate with a .NET Core backend.
Use Case: Combining React and .NET Core allows you to build a full-stack application with a modern frontend and a powerful backend.
dotnet new react -o MyReactApp cd MyReactApp dotnet run
How do you handle API requests from React to .NET Core?
Answer: API requests from React to .NET Core are handled using libraries like Axios or Fetch. The backend endpoints are called from React components, and the responses are processed accordingly.
Use Case: Use Axios or Fetch to perform CRUD operations from a React frontend to a .NET Core backend.
import axios from 'axios'; function fetchData() { axios.get('/api/data') .then(response => { console.log(response.data); }) .catch(error => { console.error('There was an error!', error); }); }
What is CORS and how do you handle it in a React and .NET Core application?
Answer: CORS (Cross-Origin Resource Sharing) is a security feature that restricts web applications from making requests to different domains. It is handled in .NET Core by configuring CORS policies in the Startup.cs file.
Use Case: Enable CORS in your .NET Core application to allow requests from a React frontend hosted on a different domain.
public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => builder.WithOrigins("<http://localhost:3000>") .AllowAnyMethod() .AllowAnyHeader()); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseCors("AllowSpecificOrigin"); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
How do you deploy a React and .NET Core application?
Answer: Deployment can be done by building the React application and serving the static files through the .NET Core backend. The combined application can then be deployed to a web server or cloud service.
Use Case: Deploy your application to a platform like Azure, AWS, or a traditional web server for production use.
# Build the React application npm run build # Copy the build output to the .NET Core public directory cp -r build/* ../MyDotNetApp/wwwroot # Deploy the .NET Core application dotnet publish -o ../MyDotNetApp/publish
How do you secure a React and .NET Core application?
Answer: Security measures include using HTTPS, JWT for authentication, setting up CORS policies, validating and sanitizing user input, and following secure coding practices.
Use Case: Implement security best practices to protect your application from common vulnerabilities and ensure safe data handling.
// Configure JWT Authentication in .NET Core services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; });
// In React, use Axios to send JWT in headers axios.get('/api/protected', { headers: { 'Authorization': `Bearer ${token}` } }) .then(response => { console.log(response.data); }) .catch(error => { console.error('There was an error!', error); });
Testing and Debugging
How do you test React components?
Answer: React components can be tested using libraries like Jest and React Testing Library. Unit tests and integration tests are written to ensure components render correctly and handle user interactions.
Use Case: Write tests to verify the behavior and correctness of your components, ensuring they work as expected and are maintainable.
// Using Jest and React Testing Library import { render, screen, fireEvent } from '@testing-library/react'; import Counter from './Counter'; test('increments counter', () => { render(<Counter />); const button = screen.getByText('Click me'); fireEvent.click(button); expect(screen.getByText('You clicked 1 times')).toBeInTheDocument(); });
What are some common debugging techniques in React?
Answer: Debugging techniques include using browser developer tools, React DevTools, logging with console statements, and using error boundaries to catch and handle errors in the component tree.
Use Case: Use these tools and techniques to identify and fix issues in your React application.
// Logging with console statements function MyComponent() { useEffect(() => { console.log('Component rendered'); }, []); return <div>Debugging Example</div>; }
How do you handle error boundaries in React?
Answer: Error boundaries in React are components that catch JavaScript errors anywhere in their child component tree, log the errors, and display a fallback UI. They are implemented using componentDidCatch and getDerivedStateFromError lifecycle methods.
Use Case: Use error boundaries to provide a user-friendly error message and prevent the entire application from crashing due to an error in a specific component.
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { // You can log the error to an error reporting service console.log(error, errorInfo); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } function MyComponent() { return ( <ErrorBoundary> <BuggyComponent /> </ErrorBoundary> ); } function BuggyComponent() { throw new Error('I crashed!'); }
Miscellaneous
Explain the role of the useEffect hook in React.
Answer: The useEffect hook is used to perform side effects in functional components, such as fetching data, setting up subscriptions, and manually changing the DOM. It runs after the component renders and can optionally clean up after itself.
Use Case: Use useEffect to handle side effects like data fetching or setting up event listeners.
import React, { useState, useEffect } from 'react'; function FetchData() { const [data, setData] = useState(null); useEffect(() => { fetch('<https://api.example.com/data>') .then(response => response.json()) .then(data => setData(data)); return () => { // Cleanup if needed }; }, []); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; } export default FetchData;
How do you manage state in a large React application?
Answer: State management in a large React application can be handled using libraries like Redux, MobX, or Context API. These tools help manage global state and keep components decoupled.
Use Case: Use Redux for a complex application where the state needs to be accessed and updated by many components. Use Context API for simpler state sharing.
import { createStore } from 'redux'; import { Provider } from 'react-redux'; // Reducer const rootReducer = (state = { count: 0 }, action) => { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 }; default: return state; } }; // Store const store = createStore(rootReducer); function App() { return ( <Provider store={store}> <Counter /> </Provider> ); } export default App; // Counter Component import { useDispatch, useSelector } from 'react-redux'; function Counter() { const count = useSelector(state => state.count); const dispatch = useDispatch(); return ( <div> <p>{count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button> </div> ); } export default Counter;
What is MobX and how is it used in React applications?
Answer: MobX is a state management library that makes state management simple and scalable by using reactive programming. MobX allows you to manage the application state outside the React components and reactively update the components when the state changes.
Use Case: Use MobX for managing state in complex applications where you need a simple, yet powerful state management solution.
import { makeAutoObservable } from 'mobx'; import { observer } from 'mobx-react'; class CounterStore { count = 0; constructor() { makeAutoObservable(this); } increment() { this.count++; } } const counterStore = new CounterStore(); const Counter = observer(() => { return ( <div> <p>{counterStore.count}</p> <button onClick={() => counterStore.increment()}>Increment</button> </div> ); }); export default Counter;
How do you implement routing in a React application?
Answer: Routing in a React application is typically handled by the react-router library. It allows you to define routes and render components based on the URL.
Use Case: Use react-router to navigate between different views or pages in your application.
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </nav> <Switch> <Route path="/about"> <About /> </Route> <Route path="/"> <Home /> </Route> </Switch> </div> </Router> ); } export default App;
How do you implement private routing in a React application?
Answer: Private routing is used to restrict access to certain routes based on authentication status. You can create a PrivateRoute component that checks if the user is authenticated before allowing access to the route.
Use Case: Use private routing to protect routes that should only be accessible by authenticated users.
import { Route, Redirect } from 'react-router-dom'; function PrivateRoute({ children, ...rest }) { const isAuthenticated = // determine if the user is authenticated return ( <Route {...rest} render={({ location }) => isAuthenticated ? ( children ) : ( <Redirect to={{ pathname: "/login", state: { from: location } }} /> ) } /> ); } export default PrivateRoute;
How do you secure a React application?
Answer: Security measures in a React application include using HTTPS, protecting routes with authentication and authorization, validating and sanitizing user inputs, and following secure coding practices.
Use Case: Implement security best practices to protect your application from common vulnerabilities and ensure safe data handling.
// Example of input validation and sanitization function handleInputChange(event) { const value = event.target.value; if (/^[a-zA-Z0-9]*$/.test(value)) { // Simple alphanumeric validation setInputValue(value); } } return ( <input type="text" onChange={handleInputChange} /> );
What is the useReducer hook in React and when would you use it?
Answer: The useReducer hook is used for managing state in a React function component. It is an alternative to useState and is especially useful for managing more complex state logic. It is similar to the concept of reducers in Redux.
Use Case: Use useReducer when you have complex state logic involving multiple sub-values or when the next state depends on the previous state.
import React, { useReducer } from 'react'; const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Count: {state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>Increment</button> <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button> </div> ); } export default Counter;
What is code splitting in React and why is it important?
Answer: Code splitting is a feature supported by bundlers like Webpack that allows you to split your code into various bundles that can be loaded on demand. It helps in reducing the initial load time by loading only the necessary code for the initial view and loading other parts of the application as needed.
Use Case: Use code splitting to improve the performance of your application by reducing the initial load time and loading only the necessary code when needed.
import React, { lazy, Suspense } from 'react'; const OtherComponent = lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> </div> ); } export default MyComponent;
How do you handle state management with React Query?
Answer: React Query is a library for fetching, caching, and updating asynchronous data in React applications. It simplifies data fetching logic and provides built-in caching, synchronization, and background updates.
Use Case: Use React Query to manage server state in your application, making it easier to handle caching, background updates, and synchronization.
import { useQuery } from 'react-query'; function fetchTodos() { return fetch('/api/todos').then(response => response.json()); } function Todos() { const { data, error, isLoading } = useQuery('todos', fetchTodos); if (isLoading) return <div>Loading...</div>; if (error) return <div>Error fetching data</div>; return ( <ul> {data.map(todo => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ); } export default Todos;
How do you handle asynchronous operations with useEffect?
Answer: Asynchronous operations can be handled within useEffect by defining an async function inside the effect and calling it. You should ensure to clean up any side effects if the component unmounts before the async operation completes.
Use Case: Use async/await inside useEffect to fetch data or perform other asynchronous tasks when the component mounts or updates.
import React, { useState, useEffect } from 'react'; function DataFetcher() { const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await fetch('/api/data'); const result = await response.json(); setData(result); } catch (err) { setError(err); } }; fetchData(); }, []); if (error) return <div>Error: {error.message}</div>; if (!data) return <div>Loading...</div>; return <div>Data: {JSON.stringify(data)}</div>; } export default DataFetcher;
How do you handle authentication in a React application?
Answer: Authentication in a React application can be handled by managing the user's authentication state (e.g., token storage) and protecting routes with higher-order components or route guards.
Use Case: Implement authentication using JWT tokens and protect routes to ensure only authenticated users can access certain parts of the application.
import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'; const isAuthenticated = () => { return !!localStorage.getItem('token'); }; const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => isAuthenticated() ? ( <Component {...props} /> ) : ( <Redirect
to="/login" />
)
}
/>
);
const Login = ({ history }) => {
const handleLogin = () => {
localStorage.setItem('token', 'your-token');
history.push('/');
};
return <button onClick={handleLogin}>Login</button>;
};
const Dashboard = () => <h2>Dashboard</h2>;
function App() {
return (
<Router>
<div>
<PrivateRoute exact path="/" component={Dashboard} />
<Route path="/login" component={Login} />
</div>
</Router>
);
}
export default App;
```
What are higher-order components (HOCs) in React and how are they used?
Answer: Higher-order components (HOCs) are functions that take a component and return a new component. They are used to reuse component logic across multiple components.
Use Case: Use HOCs to add common functionality like logging, authorization checks, or theming to components without modifying the component itself.
import React from 'react'; function withLogging(WrappedComponent) { return class extends React.Component { componentDidMount() { console.log(`Component ${WrappedComponent.name} mounted`); } render() { return <WrappedComponent {...this.props} />; } }; } function MyComponent() { return <div>Hello, World!</div>; } const MyComponentWithLogging = withLogging(MyComponent); export default MyComponentWithLogging;
How do you handle error handling in React using Error Boundaries?
Answer: Error boundaries are React components that catch JavaScript errors in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.
Use Case: Use error boundaries to catch and handle errors in a specific part of your application and display a user-friendly error message.
import React from 'react'; class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.log(error, errorInfo); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } function BuggyComponent() { throw new Error('I crashed!'); } function App() { return ( <ErrorBoundary> <BuggyComponent /> </ErrorBoundary> ); } export default App;
What are controlled and uncontrolled components in React?
Answer: Controlled components are components whose form data is handled by the component's state, while uncontrolled components manage their own state internally via the DOM.
Use Case: Use controlled components for more complex forms where you need to control and validate the form data, and use uncontrolled components for simpler forms where you don't need to manage state.
// Controlled Component function ControlledInput() { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; return ( <input type="text" value={value} onChange={handleChange} /> ); } // Uncontrolled Component function UncontrolledInput() { const inputRef = React.useRef(); const handleSubmit = (e) => { e.preventDefault(); alert(inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">Submit</button> </form> ); } export { ControlledInput, UncontrolledInput };
What is a memoized selector and how is it used in React with Redux?
Answer: A memoized selector is a function that caches its result based on its inputs and only recalculates if the inputs change. This helps to optimize performance by preventing unnecessary recalculations.
Use Case: Use memoized selectors with Redux to efficiently compute derived state and avoid unnecessary re-renders.
import { createSelector } from 'reselect'; const selectItems = (state) => state.items; const selectFilter = (state) => state.filter; const selectFilteredItems = createSelector( [selectItems, selectFilter], (items, filter) => { return items.filter(item => item.name.includes(filter)); } ); function MyComponent({ items, filter }) { const filteredItems = selectFilteredItems({ items, filter }); return ( <ul> {filteredItems.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> ); } export default MyComponent;
How do you handle side effects with Redux Thunk?
Answer: Redux Thunk is a middleware that allows you to write action creators that return a function instead of an action. This function can then perform asynchronous operations and dispatch actions based on the result.
Use Case: Use Redux Thunk to handle asynchronous logic such as data fetching within your Redux actions.
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; const initialState = { data: null, loading: false, error: null }; function reducer(state = initialState, action) { switch (action.type) { case 'FETCH_DATA_REQUEST': return { ...state, loading: true }; case 'FETCH_DATA_SUCCESS': return { ...state, loading: false, data: action.payload }; case 'FETCH_DATA_FAILURE': return { ...state, loading: false, error: action.error }; default: return state; } } function fetchData() { return async (dispatch) => { dispatch({ type: 'FETCH_DATA_REQUEST' }); try { const response = await fetch('/api/data'); const data = await response.json(); dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data }); } catch (error) { dispatch({ type: 'FETCH_DATA_FAILURE', error }); } }; } const store = createStore(reducer, applyMiddleware(thunk)); function MyComponent() { const dispatch = useDispatch(); const data = useSelector(state => state.data); const loading = useSelector(state => state.loading); const error = useSelector(state => state.error); useEffect(() => { dispatch(fetchData()); }, [dispatch]); if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; return <div>Data: {JSON.stringify(data)}</div>; } export default MyComponent;
What is server-side rendering (SSR) in React and why is it used?
Answer: Server-side rendering (SSR) is the process of rendering web pages on the server instead of in the browser. In React, SSR can be implemented using frameworks like Next.js. SSR improves the initial load time and SEO by delivering a fully rendered page to the client.
Use Case: Use SSR to enhance performance and SEO for content-heavy applications.
// Example using Next.js import React from 'react'; const Home = ({ data }) => ( <div> <h1>Data fetched from server</h1> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); export async function getServerSideProps() { const res = await fetch('<https://api.example.com/data>'); const data = await res.json(); return { props: { data } }; } export default Home;
How do you handle forms validation in React?
Answer: Form validation in React can be handled using libraries like Formik, Yup, or React Hook Form. These libraries provide easy ways to manage form state, validation, and submission.
Use Case: Use Formik and Yup to handle form validation and submission.
import React from 'react'; import { useFormik } from 'formik'; import * as Yup from 'yup'; const SignupForm = () => { const formik = useFormik({ initialValues: { email: '', password: '' }, validationSchema: Yup.object({ email: Yup.string().email('Invalid email address').required('Required'), password: Yup.string().min(6, 'Must be 6 characters or more').required('Required') }), onSubmit: values => { alert(JSON.stringify(values, null, 2)); } }); return ( <form onSubmit={formik.handleSubmit}> <label htmlFor="email">Email</label> <input id="email" name="email" type="email" onChange={formik.handleChange} value={formik.values.email} /> {formik.errors.email ? <div>{formik.errors.email}</div> : null} <label htmlFor="password">Password</label> <input id="password" name="password" type="password" onChange={formik.handleChange} value={formik.values.password} /> {formik.errors.password ? <div>{formik.errors.password}</div> : null} <button type="submit">Submit</
button>
</form>
);
};
export default SignupForm;
```
How do you implement internationalization (i18n) in a React application?
Answer: Internationalization in React can be implemented using libraries like react-i18next. These libraries provide tools to manage translations, detect the user's language, and format dates and numbers according to locale.
Use Case: Use react-i18next to provide multilingual support in your application.
import React from 'react'; import { useTranslation } from 'react-i18next'; const App = () => { const { t, i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); }; return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('de')}>German</button> <h1>{t('welcome_message')}</h1> </div> ); }; export default App;
What are React portals and how are they used?
Answer: React portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is useful for rendering modals, tooltips, and other overlay components.
Use Case: Use portals to render a modal component.
import React from 'react'; import ReactDOM from 'react-dom'; const Modal = ({ children }) => { return ReactDOM.createPortal( <div className="modal"> {children} </div>, document.getElementById('modal-root') ); }; export default Modal;
How do you implement lazy loading images in React?
Answer: Lazy loading images can be implemented using the loading="lazy" attribute or by using libraries like react-lazyload. This improves performance by loading images only when they are about to enter the viewport.
Use Case: Use the loading="lazy" attribute to lazy load images.
import React from 'react'; const ImageComponent = () => { return ( <div> <img src="path/to/image.jpg" alt="Example" loading="lazy" /> </div> ); }; export default ImageComponent;
How do you handle file uploads in React?
Answer: File uploads in React can be handled using the input type="file" and FormData to send the file to the server. Libraries like react-dropzone can provide a drag-and-drop interface for file uploads.
Use Case: Use FormData to upload a file to the server.
import React, { useState } from 'react'; import axios from 'axios'; const FileUpload = () => { const [file, setFile] = useState(null); const handleFileChange = (e) => { setFile(e.target.files[0]); }; const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(); formData.append('file', file); axios.post('/upload', formData) .then(response => { console.log('File uploaded successfully', response.data); }) .catch(error => { console.error('There was an error uploading the file!', error); }); }; return ( <form onSubmit={handleSubmit}> <input type="file" onChange={handleFileChange} /> <button type="submit">Upload</button> </form> ); }; export default FileUpload;
How do you handle CSS in React?
Answer: CSS in React can be handled using traditional CSS files, CSS Modules, inline styles, or CSS-in-JS libraries like styled-components and Emotion.
Use Case: Use CSS Modules to scope styles locally to a component, preventing conflicts.
// Example with CSS Modules import styles from './Button.module.css'; function Button() { return <button className={styles.button}>Click me</button>; } export default Button;
What are CSS Modules in React?
Answer: CSS Modules are CSS files where all class and animation names are scoped locally by default. This prevents naming conflicts by generating unique class names.
Use Case: Use CSS Modules for component-specific styles to avoid conflicts.
// Button.module.css .button { background-color: blue; color: white; } // Button.js import styles from './Button.module.css'; function Button() { return <button className={styles.button}>Click me</button>; } export default Button;
How do you use styled-components in React?
Answer: styled-components is a library for writing CSS in JavaScript. It allows you to style React components using tagged template literals.
Use Case: Use styled-components to manage component styles within the same file.
import styled from 'styled-components'; const Button = styled.button` background-color: blue; color: white; `; function App() { return <Button>Click me</Button>; } export default App;
What is the difference between useMemo and useCallback?
Answer: useMemo is used to memoize a value, while useCallback is used to memoize a function. Both are used to optimize performance by avoiding unnecessary recalculations or re-creations of values and functions.
Use Case: Use useMemo for expensive calculations and useCallback for memoizing event handlers.
import React, { useMemo, useCallback } from 'react'; function MyComponent({ items }) { const total = useMemo(() => items.reduce((sum, item) => sum + item.value, 0), [items]); const handleClick = useCallback(() => { console.log('Button clicked'); }, []); return ( <div> <p>Total: {total}</p> <button onClick={handleClick}>Click me</button> </div> ); } export default MyComponent;
What is the purpose of React's useRef hook?
Answer: useRef is a hook that returns a mutable ref object whose .current property is initialized to the passed argument. It can be used to persist values across renders without causing a re-render.
Use Case: Use useRef to access DOM elements directly or store a mutable value that doesn't cause re-renders.
import React, { useRef } from 'react'; function TextInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus Input</button> </div> ); } export default TextInput;
How do you create a custom hook in React?
Answer: A custom hook is a JavaScript function whose name starts with "use" and that may call other hooks. It allows you to extract and reuse stateful logic across multiple components.
Use Case: Create a custom hook to fetch data and share the logic across components.
import { useState, useEffect } from 'react'; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => { setData(data); setLoading(false); }); }, [url]); return { data, loading }; } export default useFetch;
What is React.memo and how does it work?
Answer: React.memo is a higher-order component that memoizes a functional component. It prevents the component from re-rendering if its props haven't changed.
Use Case: Use React.memo to optimize performance by preventing unnecessary re-renders of pure components.
import React from 'react'; const MyComponent = React.memo(({ value }) => { console.log('Rendering MyComponent'); return <div>{value}</div>; }); export default MyComponent;
How do you implement context with a class component?
Answer: Context can be implemented in class components using the contextType property or the Consumer component.
Use Case: Use contextType for a single context and Consumer for multiple contexts.
import React, { createContext, Component } from 'react'; const MyContext = createContext(); class MyComponent extends Component { static contextType = MyContext; render() { const value = this.context; return <div>{value}</div>; } } function App() { return ( <MyContext.Provider value="Hello, World!"> <MyComponent /> </MyContext.Provider> ); } export default App;
**How do you handle side effects in a
functional component?**
**Answer:** Side effects in functional components are handled using the `useEffect` hook. It allows you to perform side effects like data fetching, subscriptions, and manual DOM manipulations.
**Use Case:** Use `useEffect` to fetch data when the component mounts.
```jsx
import React, { useState, useEffect } from 'react';
function DataFetcher({ url }) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setData(data));
}, [url]);
return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}
export default DataFetcher;
```
What are compound components in React?
Answer: Compound components are components that work together to build a more complex component. They allow for more flexible and reusable component structures.
Use Case: Use compound components to create a customizable dropdown menu.
import React from 'react'; function Dropdown({ children }) { return <div className="dropdown">{children}</div>; } function DropdownToggle({ children }) { return <button className="dropdown-toggle">{children}</button>; } function DropdownMenu({ children }) { return <div className="dropdown-menu">{children}</div>; } Dropdown.Toggle = DropdownToggle; Dropdown.Menu = DropdownMenu; export default Dropdown; // Usage import Dropdown from './Dropdown'; function App() { return ( <Dropdown> <Dropdown.Toggle>Toggle</Dropdown.Toggle> <Dropdown.Menu>Menu</Dropdown.Menu> </Dropdown> ); } export default App;
What is the difference between client-side routing and server-side routing?
Answer: Client-side routing handles navigation within a single-page application without refreshing the entire page. Server-side routing involves the server handling navigation and returning a new HTML page for each route.
Use Case: Use client-side routing with React Router to create a seamless single-page application experience.
How do you handle accessibility in React applications?
Answer: Accessibility in React applications can be handled using semantic HTML, ARIA attributes, and accessibility testing tools. React also provides the react-a11y library for linting accessibility issues.
Use Case: Use semantic HTML and ARIA attributes to make a form accessible.
function AccessibleForm() { return ( <form> <label htmlFor="name">Name</label> <input id="name" type="text" aria-required="true" /> <button type="submit">Submit</button> </form> ); } export default AccessibleForm;
What are error boundaries and how do you implement them in functional components?
Answer: Error boundaries in React are components that catch JavaScript errors in their child component tree and display a fallback UI. They are implemented using class components, but you can use hooks like useErrorHandler from the react-error-boundary library in functional components.
Use Case: Use error boundaries to catch errors in a specific part of the component tree.
import React from 'react'; import { ErrorBoundary, useErrorHandler } from 'react-error-boundary'; function BuggyComponent() { const handleError = useErrorHandler(); const throwError = () => { try { throw new Error('An error occurred!'); } catch (error) { handleError(error); } }; return <button onClick={throwError}>Throw Error</button>; } function App() { return ( <ErrorBoundary FallbackComponent={() => <div>Something went wrong.</div>}> <BuggyComponent /> </ErrorBoundary> ); } export default App;
How do you test asynchronous code in React?
Answer: Asynchronous code in React can be tested using Jest and React Testing Library. You can use async/await in your tests and utilities like waitFor to handle asynchronous updates.
Use Case: Test a component that fetches data asynchronously.
import { render, screen, waitFor } from '@testing-library/react'; import DataFetcher from './DataFetcher'; test('fetches and displays data', async () => { render(<DataFetcher url="/api/data" />); await waitFor(() => expect(screen.getByText(/data/i)).toBeInTheDocument()); });
What is the purpose of React's Profiler API?
Answer: React's Profiler API is used to measure the performance of React applications. It collects timing information about each component's render lifecycle, allowing developers to identify performance bottlenecks.
Use Case: Use the Profiler to identify and optimize slow components.
import React, { Profiler } from 'react'; function onRenderCallback(id, phase, actualDuration, baseDuration, startTime, commitTime) { console.log(`Rendered ${id} in ${actualDuration}ms`); } function App() { return ( <Profiler id="App" onRender={onRenderCallback}> <MyComponent /> </Profiler> ); } export default App;
How do you handle component state with hooks?
Answer: Component state with hooks is handled using the useState hook. This hook allows you to add state to functional components.
Use Case: Use useState to manage form input state.
import React, { useState } from 'react'; function Form() { const [input, setInput] = useState(''); return ( <form> <input value={input} onChange={(e) => setInput(e.target.value)} /> <p>{input}</p> </form> ); } export default Form;
What is the difference between React's useState and useReducer hooks?
Answer: useState is used for managing simple state in a component, while useReducer is used for managing more complex state logic, especially when the state depends on previous states or involves multiple sub-values.
Use Case: Use useReducer for complex form state management.
import React, { useReducer } from 'react'; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, { count: 0 }); return ( <div> <p>Count: {state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>Increment</button> <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button> </div> ); } export default Counter;
How do you handle conditional rendering in React?
Answer: Conditional rendering in React is handled using JavaScript conditional operators like if, ternary, and logical &&.
Use Case: Use the ternary operator to conditionally render components.
import React, { useState } from 'react'; function App() { const [isLoggedIn, setIsLoggedIn] = useState(false); return ( <div> {isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>} <button onClick={() => setIsLoggedIn(!isLoggedIn)}> {isLoggedIn ? 'Log out' : 'Log in'} </button> </div> ); } export default App;
How do you handle events in React?
Answer: Events in React are handled using synthetic events, which are wrappers around the browser's native events. Event handlers are passed as props to elements.
Use Case: Handle a button click event to update state.
import React, { useState } from 'react'; function App() { const [count, setCount] = useState(0); const handleClick = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={handleClick}>Increment</button> </div> ); } export default App;
How do you manage side effects in a React component?
Answer: Side effects in React components are managed using the useEffect hook. This hook runs after the component renders and can clean up after itself.
Use Case: Use useEffect to fetch data when the component mounts.
import React, { useState, useEffect } from 'react'; function DataFetcher({ url }) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => setData(data)); }, [url]); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; } export default DataFetcher
;
```
What is reconciliation in React?
Answer: Reconciliation is the process by which React updates the DOM with minimal changes. React maintains a virtual DOM and compares it with the actual DOM to determine the least expensive way to update the UI.
Use Case: React's reconciliation algorithm helps optimize rendering performance by updating only the parts of the DOM that have changed.
How do you use the useContext hook in React?
Answer: The useContext hook is used to access the value of a context within a functional component. It simplifies consuming context values without needing a context consumer.
Use Case: Use useContext to access a theme value from a context.
import React, { createContext, useContext } from 'react'; const ThemeContext = createContext('light'); function ThemedComponent() { const theme = useContext(ThemeContext); return <div className={`theme-${theme}`}>Current theme: {theme}</div>; } function App() { return ( <ThemeContext.Provider value="dark"> <ThemedComponent /> </ThemeContext.Provider> ); } export default App;
What is the purpose of keys in React?
Answer: Keys in React are used to uniquely identify elements in a list. They help React optimize rendering by tracking changes, additions, and deletions of elements.
Use Case: Use keys to ensure efficient updates when rendering a list of items.
import React from 'react'; function ItemList({ items }) { return ( <ul> {items.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> ); } export default ItemList;
How do you handle form submissions in React?
Answer: Form submissions in React are handled by attaching an onSubmit event handler to the form element. This handler can prevent the default form submission and handle the form data within the component.
Use Case: Handle form submission and validate form inputs.
import React, { useState } from 'react'; function Form() { const [name, setName] = useState(''); const handleSubmit = (e) => { e.preventDefault(); alert(`Submitting name: ${name}`); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input value={name} onChange={(e) => setName(e.target.value)} /> </label> <button type="submit">Submit</button> </form> ); } export default Form;
What is the purpose of React's strict mode?
Answer: React's strict mode is a development tool that helps identify potential problems in an application. It activates additional checks and warnings for its descendants.
Use Case: Use strict mode to catch unsafe lifecycles, legacy API usage, and other potential issues.
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
How do you use the useRef hook to access DOM elements?
Answer: The useRef hook returns a mutable ref object that persists for the lifetime of the component. You can attach it to a DOM element and access it directly.
Use Case: Use useRef to focus an input element.
import React, { useRef } from 'react'; function TextInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus Input</button> </div> ); } export default TextInput;
What is the difference between controlled and uncontrolled components?
Answer: Controlled components have their form data controlled by the React state, whereas uncontrolled components store their own state internally within the DOM.
Use Case: Use controlled components for more complex forms where you need to control and validate the form data, and use uncontrolled components for simpler forms where you don't need to manage state.
// Controlled Component import React, { useState } from 'react'; function ControlledInput() { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; return ( <input type="text" value={value} onChange={handleChange} /> ); } // Uncontrolled Component import React, { useRef } from 'react'; function UncontrolledInput() { const inputRef = React.useRef(); const handleSubmit = (e) => { e.preventDefault(); alert(inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">Submit</button> </form> ); } export { ControlledInput, UncontrolledInput };
How do you handle global state management in React?
Answer: Global state management in React can be handled using Context API, Redux, MobX, or Zustand. These libraries help manage state that needs to be accessed across multiple components.
Use Case: Use Redux for managing complex global state with middleware and dev tools support.
import { createStore } from 'redux'; import { Provider } from 'react-redux'; // Reducer const rootReducer = (state = { count: 0 }, action) => { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 }; default: return state; } }; // Store const store = createStore(rootReducer); function App() { return ( <Provider store={store}> <Counter /> </Provider> ); } export default App; // Counter Component import { useDispatch, useSelector } from 'react-redux'; function Counter() { const count = useSelector(state => state.count); const dispatch = useDispatch(); return ( <div> <p>{count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button> </div> ); } export default Counter;
What is the purpose of React's useImperativeHandle hook?
Answer: The useImperativeHandle hook is used with React.forwardRef to customize the instance value that is exposed when using refs. It allows you to control which instance values are accessible.
Use Case: Use useImperativeHandle to expose imperative methods from a functional component.
import React, { useRef, useImperativeHandle, forwardRef } from 'react'; const FancyInput = forwardRef((props, ref) => { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} />; }); function ParentComponent() { const inputRef = useRef(); return ( <div> <FancyInput ref={inputRef} /> <button onClick={() => inputRef.current.focus()}>Focus Input</button> </div> ); } export default ParentComponent;
What is the difference between useEffect and useLayoutEffect?
Answer: useEffect runs asynchronously after the component renders, while useLayoutEffect runs synchronously after all DOM mutations. useLayoutEffect is useful for reading layout and performing synchronous updates.
Use Case: Use useLayoutEffect for measurements and DOM manipulations that need to happen before the browser paints.
How do you optimize React components to prevent unnecessary re-renders?
Answer: React components can be optimized to prevent unnecessary re-renders using React.memo, useMemo, useCallback, and avoiding anonymous functions in JSX.
Use Case: Use React.memo to memoize functional components.
import React, { memo } from 'react'; const MyComponent = memo(({ value }) => { console.log('Rendering MyComponent'); return <div>{value}</div>; }); export default MyComponent;
How do you handle routing in a React application?
Answer: Routing in a React application is typically handled by the react-router library. It allows you to define routes and render components based on the URL.
Use Case: Use react-router to navigate between different views or pages in your application.
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function App() { return ( <Router> <div> <nav> <ul
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
```
What is the purpose of React's useMemo hook?
Answer: The useMemo hook is used to memoize a value. It recomputes the value only when its dependencies change, which helps optimize performance by avoiding expensive calculations on every render.
Use Case: Use useMemo to memoize a derived state value.
import React, { useMemo } from 'react'; function MyComponent({ items }) { const total = useMemo(() => items.reduce((sum, item) => sum + item.value, 0), [items]); return <div>Total: {total}</div>; } export default MyComponent;
How do you handle error boundaries in React?
Answer: Error boundaries in React are components that catch JavaScript errors in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.
Use Case: Use error boundaries to provide a user-friendly error message and prevent the entire application from crashing due to an error in a specific component.
import React from 'react'; class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.log(error, errorInfo); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } function BuggyComponent() { throw new Error('I crashed!'); } function App() { return ( <ErrorBoundary> <BuggyComponent /> </ErrorBoundary> ); } export default App;
How do you manage state in a large React application?
Answer: State management in a large React application can be handled using libraries like Redux, MobX, or Context API. These tools help manage global state and keep components decoupled.
Use Case: Use Redux for a complex application where the state needs to be accessed and updated by many components.
import { createStore } from 'redux'; import { Provider } from 'react-redux'; // Reducer const rootReducer = (state = { count: 0 }, action) => { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + 1 }; default: return state; } }; // Store const store = createStore(rootReducer); function App() { return ( <Provider store={store}> <Counter /> </Provider> ); } export default App; // Counter Component import { useDispatch, useSelector } from 'react-redux'; function Counter() { const count = useSelector(state => state.count); const dispatch = useDispatch(); return ( <div> <p>{count}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button> </div> ); } export default Counter;
What is the difference between controlled and uncontrolled components in React?
Answer: Controlled components have their form data controlled by the React state, while uncontrolled components manage their own state internally via the DOM.
Use Case: Use controlled components for form elements whose values are controlled by the component's state.
// Controlled Component import React, { useState } from 'react'; function ControlledInput() { const [value, setValue] = useState(''); const handleChange = (e) => { setValue(e.target.value); }; return ( <input type="text" value={value} onChange={handleChange} /> ); } // Uncontrolled Component import React, { useRef } from 'react'; function UncontrolledInput() { const inputRef = React.useRef(); const handleSubmit = (e) => { e.preventDefault(); alert(inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">Submit</button> </form> ); } export { ControlledInput, UncontrolledInput };
What is the purpose of React's useReducer hook?
Answer: The useReducer hook is used for managing state in a React function component. It is an alternative to useState and is especially useful for managing more complex state logic. It is similar to the concept of reducers in Redux.
Use Case: Use useReducer for complex form state management.
import React, { useReducer } from 'react'; function reducer(state, action) { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, { count: 0 }); return ( <div> <p>Count: {state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>Increment</button> <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button> </div> ); } export default Counter;
How do you implement server-side rendering (SSR) in React?
Answer: Server-side rendering (SSR) in React is implemented using frameworks like Next.js. SSR improves the initial load time and SEO by delivering a fully rendered page to the client.
Use Case: Use SSR to enhance performance and SEO for content-heavy applications.
// Example using Next.js import React from 'react'; const Home = ({ data }) => ( <div> <h1>Data fetched from server</h1> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); export async function getServerSideProps() { const res = await fetch('<https://api.example.com/data>'); const data = await res.json(); return { props: { data } }; } export default Home;
How do you handle forms validation in React?
Answer: Form validation in React can be handled using libraries like Formik, Yup, or React Hook Form. These libraries provide easy ways to manage form state, validation, and submission.
Use Case: Use Formik and Yup to handle form validation and submission.
import React from 'react'; import { useFormik } from 'formik'; import * as Yup from 'yup'; const SignupForm = () => { const formik = useFormik({ initialValues: { email: '', password: '' }, validationSchema: Yup.object({ email: Yup.string().email('Invalid email address').required('Required'), password: Yup.string().min(6, 'Must be 6 characters or more').required('Required') }), onSubmit: values => { alert(JSON.stringify(values, null, 2)); } }); return ( <form onSubmit={formik.handleSubmit}> <label htmlFor="email">Email</label> <input id="email" name="email" type="email" onChange={formik.handleChange} value={formik.values.email} /> {formik.errors.email ? <div>{formik.errors.email}</div> : null} <label htmlFor="password">Password</label> <input id="password" name="password" type="password" onChange={formik.handleChange} value={formik.values.password} /> {formik.errors.password ? <div>{formik.errors.password}</div> : null} <button type="submit">Submit</button> </form> ); }; export default SignupForm;
How do you implement internationalization (i18n) in a React application?
Answer: Internationalization in React can be implemented using libraries like react-i18next. These libraries provide tools to manage translations, detect the user's language, and format dates and numbers according to locale.
Use Case: Use react-i18next to provide multilingual support in your application.
import React from 'react'; import { useTranslation } from 'react-i18next'; const App = () => { const { t, i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); }; return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => change
Language('de')}>German</button>
<h1>{t('welcome_message')}</h1>
</div>
);
};
export default App;
```
What are React portals and how are they used?
Answer: React portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is useful for rendering modals, tooltips, and other overlay components.
Use Case: Use portals to render a modal component.
import React from 'react'; import ReactDOM from 'react-dom'; const Modal = ({ children }) => { return ReactDOM.createPortal( <div className="modal"> {children} </div>, document.getElementById('modal-root') ); }; export default Modal;
How do you implement lazy loading images in React?
Answer: Lazy loading images can be implemented using the loading="lazy" attribute or by using libraries like react-lazyload. This improves performance by loading images only when they are about to enter the viewport.
Use Case: Use the loading="lazy" attribute to lazy load images.
import React from 'react'; const ImageComponent = () => { return ( <div> <img src="path/to/image.jpg" alt="Example" loading="lazy" /> </div> ); }; export default ImageComponent;
How do you handle file uploads in React?
Answer: File uploads in React can be handled using the input type="file" and FormData to send the file to the server. Libraries like react-dropzone can provide a drag-and-drop interface for file uploads.
Use Case: Use FormData to upload a file to the server.
import React, { useState } from 'react'; import axios from 'axios'; const FileUpload = () => { const [file, setFile] = useState(null); const handleFileChange = (e) => { setFile(e.target.files[0]); }; const handleSubmit = (e) => { e.preventDefault(); const formData = new FormData(); formData.append('file', file); axios.post('/upload', formData) .then(response => { console.log('File uploaded successfully', response.data); }) .catch(error => { console.error('There was an error uploading the file!', error); }); }; return ( <form onSubmit={handleSubmit}> <input type="file" onChange={handleFileChange} /> <button type="submit">Upload</button> </form> ); }; export default FileUpload;
How do you handle CSS in React?
Answer: CSS in React can be handled using traditional CSS files, CSS Modules, inline styles, or CSS-in-JS libraries like styled-components and Emotion.
Use Case: Use CSS Modules to scope styles locally to a component, preventing conflicts.
// Example with CSS Modules import styles from './Button.module.css'; function Button() { return <button className={styles.button}>Click me</button>; } export default Button;
What are CSS Modules in React?
Answer: CSS Modules are CSS files where all class and animation names are scoped locally by default. This prevents naming conflicts by generating unique class names.
Use Case: Use CSS Modules for component-specific styles to avoid conflicts.
// Button.module.css .button { background-color: blue; color: white; } // Button.js import styles from './Button.module.css'; function Button() { return <button className={styles.button}>Click me</button>; } export default Button;
How do you use styled-components in React?
Answer: styled-components is a library for writing CSS in JavaScript. It allows you to style React components using tagged template literals.
Use Case: Use styled-components to manage component styles within the same file.
import styled from 'styled-components'; const Button = styled.button` background-color: blue; color: white; `; function App() { return <Button>Click me</Button>; } export default App;
What is the difference between useMemo and useCallback?
Answer: useMemo is used to memoize a value, while useCallback is used to memoize a function. Both are used to optimize performance by avoiding unnecessary recalculations or re-creations of values and functions.
Use Case: Use useMemo for expensive calculations and useCallback for memoizing event handlers.
import React, { useMemo, useCallback } from 'react'; function MyComponent({ items }) { const total = useMemo(() => items.reduce((sum, item) => sum + item.value, 0), [items]); const handleClick = useCallback(() => { console.log('Button clicked'); }, []); return ( <div> <p>Total: {total}</p> <button onClick={handleClick}>Click me</button> </div> ); } export default MyComponent;
What is the purpose of React's useRef hook?
Answer: useRef is a hook that returns a mutable ref object whose .current property is initialized to the passed argument. It can be used to persist values across renders without causing a re-render.
Use Case: Use useRef to access DOM elements directly or store a mutable value that doesn't cause re-renders.
import React, { useRef } from 'react'; function TextInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus Input</button> </div> ); } export default TextInput;
How do you create a custom hook in React?
Answer: A custom hook is a JavaScript function whose name starts with "use" and that may call other hooks. It allows you to extract and reuse stateful logic across multiple components.
Use Case: Create a custom hook to fetch data and share the logic across components.
import { useState, useEffect } from 'react'; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => { setData(data); setLoading(false); }); }, [url]); return { data, loading }; } export default useFetch;
What is React.memo and how does it work?
Answer: React.memo is a higher-order component that memoizes a functional component. It prevents the component from re-rendering if its props haven't changed.
Use Case: Use React.memo to optimize performance by preventing unnecessary re-renders of pure components.
import React from 'react'; const MyComponent = React.memo(({ value }) => { console.log('Rendering MyComponent'); return <div>{value}</div>; }); export default MyComponent;
How do you implement context with a class component?
Answer: Context can be implemented in class components using the contextType property or the Consumer component.
Use Case: Use contextType for a single context and Consumer for multiple contexts.
import React, { createContext, Component } from 'react'; const MyContext = createContext(); class MyComponent extends Component { static contextType = MyContext; render() { const value = this.context; return <div>{value}</div>; } } function App() { return ( <MyContext.Provider value="Hello, World!"> <MyComponent /> </MyContext.Provider> ); } export default App;
How do you handle side effects in a functional component?
Answer: Side effects in functional components are handled using the useEffect hook. It allows you to perform side effects like data fetching, subscriptions, and manual DOM manipulations.
Use Case: Use useEffect to fetch data when the component mounts.
import React, { useState, useEffect } from 'react'; function DataFetcher({ url }) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then(response => response.json()) .then(data => setData(data)); }, [url]); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; } export default DataFetcher;
Comments
Post a Comment