The Complete Frontend Guide
The Complete Frontend Guide
Learn HTML
Learn CSS and styling
Websites
Videos
Learn OOPS - very important
Resources
Interfaces in React
MVP architecture
React learning resources
Websites
Videos
NEXT JS resources
50 React interview questions
50 Next JS interview questions
10 React questions with implementation
10 Next JS questions with implementation
Learn HTML
The HTML documentation on the Mozilla Developer Network:
https://developer.mozilla.org/en-US/docs/Web/HTML
The "Learn HTML5, CSS3, and Responsive WebSite Design in One Go!" course on Udemy:
https://www.udemy.com/course/learn-html5-css3-and-responsive-website-design-in-
one-go/
The "Advanced CSS and Sass: Flexbox, Grid, Animations and More!" course on Udemy:
https://www.udemy.com/course/advanced-css-and-sass/
The "Styling and Customizing React Components" article on the LogRocket blog:
https://blog.logrocket.com/styling-and-customizing-react-components/
Videos
"CSS Crash Course For Absolute Beginners" by Traversy Media:
https://www.youtube.com/watch?v=yfoY53QXEnI
4. Encapsulation: The process of wrapping the data and behavior of an object or class into a
single unit. This allows for better control over the data and behavior of the object or class, and
helps to prevent unintended changes or side effects.
5. Interfaces: A set of rules or contracts that define the expected behavior of a class or object.
Interfaces allow for better code organization and abstraction, and enable polymorphism by
allowing different classes to implement the same interface and be used interchangeably.
Resources
1. "Object-Oriented Programming in JavaScript" by Eric Elliott: https://medium.com/javascript-
scene/object-oriented-programming-in-javascript-a96f74351b72
In object-oriented programming (OOP), an interface is a set of rules or contracts that define the
expected behavior of a class or object. An interface specifies the signature of a set of methods,
properties, or events, without providing an implementation for those members.
Interfaces allow for better code organization and abstraction, and enable polymorphism by
allowing different classes to implement the same interface and be used interchangeably.
Here is an example of how to use interfaces in a JavaScript OOP codebase:
In this example, the IVehicle interface defines the signature of the start method and the speed
property. The Car class implements the IVehicle interface, providing an implementation for the
start method and the speed property.
The Car class can be treated as an instance of the IVehicle interface, and can be used
interchangeably with other classes that implement the same interface. This allows for flexibility
and modularity in the code, and ensures that the classes that implement the interface adhere to
the specified rules and contracts.
Interfaces in React
In a React application, interfaces can be used to define the expected shape of the data that is
passed to components as props. This allows for better type checking and type safety in the code,
and helps to prevent unintended errors or bugs.
Here is an example of how to use an interface to define the expected shape of the props in a
React component:
In this example, the IUser interface defines the shape of the name and age properties that are
expected to be passed to the UserCard component as props. The UserCard component is defined
with the props parameter typed as the IUser interface, which ensures that the props object has
the expected shape.
The UserCard component is then rendered with the user object as props, which matches the
shape of the IUser interface. This ensures that the component receives the correct data and can
render it correctly. Using an interface in this way helps to prevent unintended errors or bugs, and
improves the type safety and maintainability of the code.
MVP architecture
The MVP (Model-View-Presenter) architecture is a design pattern that is commonly used in
software development. It is an adaptation of the MVC (Model-View-Controller) architecture, which
separates the application into three main components: the model, the view, and the controller.
In the MVP architecture, the controller is replaced by the presenter, which is responsible for
managing the interactions between the model and the view. The model represents the data and
the business logic of the application, the view represents the user interface, and the presenter
acts as a mediator between the model and the view.
// define a method named "setName" that updates the model and the view
setName(name: string) {
// update the "name" property of the model
this.userModel.setName(name);
In this example, the UserModel class represents the model and contains the data and the business
logic of the application. The UserView class represents the view and is responsible for rendering
the user interface. The UserPresenter class represents the presenter and acts as a mediator
between the model and the view.
The UserPresenter class updates the UserModel with the new name property, and then updates the
UserViewwith the new name property. This allows the model and the view to be decoupled and
independent of each other, and allows the presenter to manage the interactions between them.
In summary, the MVP architecture allows for better separation of concerns and modularity in the
code, and makes it easier to maintain and extend the application. It also allows for better
testability and flexibility, as the components can be tested and swapped out independently
Videos
"React JS - Build real world JS apps & deploy on cloud" by LearnCode.academy:
https://www.youtube.com/watch?v=MhkGQAoc7bc
"React - The Complete Guide (incl Hooks, React Router, Redux)" by Academind:
https://www.youtube.com/watch?v=Ke90Tje7VS0
"The Complete React Developer Course (w/ Hooks and Redux)" by Andrew Mead:
https://www.youtube.com/watch?v=MhkGQAoc7bc
NEXT JS resources
10. What is the difference between "client-side" and "server-side" rendering in React?
11. What is the difference between "functional" and "object-oriented" programming in the context
of React?
14. What is the difference between "static" and "dynamic" typing in the context of React?
18. What is the difference between "immutable" and "mutable" data in the context of React?
20. What is the purpose of the "lazy" and "suspense" APIs in React?
21. What is the difference between a "function" and a "generator" in the context of React?
22. How do you implement optimistic and pessimistic concurrency in a React application?
23. What is the difference between "object" and "array" destructuring in the context of React?
24. What is the difference between a "map" and a "set" in the context of React?
26. What is the difference between a "callback" and a "promise" in the context of React?
27. What is the difference between a "spread" and a "rest" operator in the context of React?
28. How do you implement lazy loading and code splitting in a React application?
29. What is the difference between a "class" and a "hook" in the context of React?
31. What is the difference between a "proxy" and a "ref" in the context of React?
32. How do you implement controlled and uncontrolled forms in a React application?
33. What is the difference between "static" and "instance" methods in the context of React?
34. What is the difference between a "portal" and an "error boundary" in the context of React?
35. How do you implement animations using the "React Transition Group" library?
36. What is the difference between "inline" and "external" conditional rendering in the context of
React?
37. What is the difference between a "memo" and a "hook" in the context of React performance
optimization?
39. What is the difference between "server-side" and "client-side" routing in the context of React?
40. How do you implement real-time data updates in a React application using websockets?
41. What is the difference between a "function" and a "hook" in the context of React performance
optimization?
42. How do you implement server-side rendering in a React application using the "Next.js"
framework?
43. What is the difference between a "stateful" and a "stateless" component in the context of
React hooks?
45. How do you implement pagination in a large data set in a React application?
46. What is the difference between a "static" and a "instance" property in the context of React
class components?
47. What is the difference between a "memoized" and a "recursive" component in the context of
React performance optimization?
49. What is the difference between a "custom" and a "built-in" hook in the context of React?
50. How do you implement server-side data fetching in a React application using the "Relay"
framework?
2. How does server-side rendering (SSR) work in Next.js and why is it useful?
3. How does static site generation (SSG) work in Next.js and when should it be used?
10. How can you integrate Next.js with a server-side backend, such as a REST API or GraphQL
API?
13. What is the difference between the prefetch and preload properties of the Link component?
14. How can you create custom error pages in a Next.js application?
16. What is the _app.js and _document.js files and how are they used in Next.js?
17. How can you enable automatic code splitting in a Next.js application?
19. How can you use the next/head component to add metadata to the document head in a
Next.js application?
20. How can you use the next/css and next/sass modules to include CSS and Sass files in a
Next.js application?
22. How can you use the next/redux module to integrate Redux with Next.js?
23. How can you use the next/router module to access the router instance in a Next.js
application?
25. How can you use the next/image component to optimize the performance of images in a
Next.js application?
26. How can you use the next/ad component to serve ads in a Next.js application?
27. How can you use the next/analytics component to track analytics in a Next.js application?
29. How can you use the next/worker module to create web workers in a Next.js application?
30. How can you use the next/dist module to access the production-ready files of a Next.js
application?
32. How can you use the next/serverless module to deploy a Next.js application as a serverless
function?
34. How can you use the next/router module to create dynamic routes in a Next.js application?
36. How can you use the next/mq module to create media queries in a Next.js application?
38. How can you use the next/experimental module to access experimental features in Next.js?
39. How can you use the next/components module to import components from external libraries in a
Next.js application?
40. What is the next/link component and how is it different from the Link component in Next.js?
42. How can you use the next/error component to handle errors in a Next.js application?
43. How can you use the next/profiler component to measure the performance of a Next.js
application?
45. How can you use the next/worker module to create web workers in a Next.js application?
47. How can you use the next/head component to add metadata to the document head in a
Next.js application?
49. How can you use the next/view-port component to create responsive designs in a Next.js
application?
50. How can you use the next/dynamic component to create components that are loaded and
rendered on demand in a Next.js application?
To implement lazy loading and code splitting in a large React application, you can use the
React.lazy and React.Suspense components. Here is an example:
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
This code uses the React.lazy component to dynamically import the LazyComponent module only
when it is needed. The React.Suspense component is used to render a loading indicator while the
LazyComponent is being loaded.
To implement server-side rendering in a React application using the "Next.js" framework, you can
use the getInitialProps method in your page components. Here is an example:
This code defines a HomePage component that renders a list of users fetched from a server-side
API. The getInitialProps method is used to fetch the data for the component on the server-side
and pass it as props to the component. This allows the component to be rendered with the data
on the server, resulting in improved performance and SEO benefits.
These are just some examples of implementation-based frontend interview questions related to
the React framework. The specific questions you will be asked and the solutions you will need to
provide will depend on the job you are applying for and the company you are interviewing with.
3. How would you implement pagination in a large data set in a React application?
To implement pagination in a large data set in a React application, you can use a pagination
component and manage the current page state using the useState hook. Here is an example:
function App() {
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 10;
To implement optimistic concurrency in a React application, you can update the local state
immediately and send the update to the server in the background. If the server returns a success
response, you can update the global state with the updated data. If the server returns an error,
you can revert the local state to the previous state and show an error message to the user. Here is
an example:
function App() {
const [globalState, setGlobalState] = useState({
data: [],
isLoading: false,
error: null
});
return (
<div>
{globalState.error && (
<p>An error occurred: {globalState.error.message}</p>
)}
<ul>
{globalState.data.map(item => (
<li key={item.id}>
{item.value}
{globalState.isLoading && item.isUpdating && (
<span>Updating...</span>
)}
{!globalState.isLoading && (
<button onClick={() => handleUpdate(item.id, 'new value')}>
Update
</button>
)}
</li>
))}
</ul>
</div>
);
}
5. How would you implement real-time data updates in a React application using
websockets?
To implement real-time data updates in a React application using websockets, you can use the
useEffect hook to subscribe to the websocket server and update the local state when new data is
function App() {
const [globalState, setGlobalState] = useState({
data: [],
isConnected: false
});
useEffect(() => {
const connection = new signalR.HubConnectionBuilder()
connection.start().then(() => {
setGlobalState(prevState => ({
...prevState,
isConnected: true
}));
});
return () => {
connection.stop();
};
}, []);
return (
<div>
{globalState.isConnected ? (
<ul>
{globalState.data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
) : (
<p>Connecting to websocket server...</p>
)}
</div>
);
}
function useCounter(initialCount) {
const [count, setCount] = useState(initialCount);
function Counter() {
const { count, increment, decrement } = useCounter(0);
return (
<div>
<p>{count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
This code calls the useCounter custom hook inside the Counter component and destructure the
returned object to use its count , increment , and decrement properties.
Custom hooks allow you to extract common logic and share it across multiple components,
making your code more modular and reusable.
7. How would you implement server-side data fetching in a React application using the
"Relay" framework?
To implement server-side data fetching in a React application using the "Relay" framework, you
can define a "query" using the graphql tag and use the useQuery hook to execute the query and
fetch the data. Here is an example:
function User({ id }) {
const { data, error } = useQuery(UserQuery, { id });
if (error) {
return <p>An error occurred: {error.message}</p>;
}
if (!data) {
return <p>Loading...</p>;
}
This code defines a UserQuery using the graphql tag and specifies the fields to be fetched for a
user with a given ID. The useQuery hook is used to execute the query and fetch the data on the
server-side. The data and error properties of the hook's return value are used to render the user
data or an error message.
To implement accessibility features in a React application, you can use the built-in aria attributes
and the htmlFor and id attributes on form elements. You can also use semantic HTML elements,
such as button , nav , and main , to provide context to screen readers. Here is an example:
function App() {
return (
<main role="main" aria-labelledby="page-title">
<h1 id="page-title">Welcome to the App</h1>
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
</ul>
</nav>
<form>
<label htmlFor="username">Username:</label>
<input type="text" id="username" />
<button type="submit">Sign In</button>
</form>
</main>
);
}
This code uses the aria attributes, the htmlFor and id attributes, and semantic HTML elements
to provide context and information to screen readers. For example, the role attribute on the main
element indicates the main content of the page, the aria-labelledby attribute on the main element
indicates the element that labels the main content, and the aria-label attribute on the nav
9. How would you implement animations using the "React Transition Group" library?
To implement animations using the "React Transition Group" library, you can use the
CSSTransition component to apply CSS transitions and animations when elements are added or
function App() {
const [isVisible, setIsVisible] = useState(false);
return (
<div>
<button onClick={toggleVisibility}>Toggle</button>
<CSSTransition
in={isVisible}
timeout={300}
classNames="fade"
unmountOnExit
>
<p>Hello, world!</p>
</CSSTransition>
</div>
);
}
This code uses the CSSTransition component to apply a fade animation when the isVisible state
is toggled. The in prop of the CSSTransition component is used to specify when the animation
should be applied, the timeout prop is used to specify the duration of the animation, the
classNames prop is used to specify the CSS class names that should be applied to the element
during the animation, and the unmountOnExit prop is used to unmount the element from the DOM
when the animation is finished.
To define the CSS transitions and animations, you can create a .fade-enter class for the initial
state, a .fade-enter-active class for the active state, a .fade-exit class for the exit state, and a
.fade-exit-active class for the exit active state:
.fade-enter {
opacity: 0;
}
.fade-enter-active {
opacity: 1;
transition: opacity 300ms;
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 300ms;
}
These classes define the initial, active, exit, and exit active states for the fade animation using the
opacity property and the transition property. The opacity property is used to control the visibility
of the element, and the transition property is used to specify the duration of the animation.
With these classes, you can use the CSSTransition component in your React application to apply
the fade animation when elements are added or removed from the DOM.
10 .How would you implement controlled and uncontrolled forms in a React application?
To implement controlled and uncontrolled forms in a React application, you can use the useState
hook to create a controlled form, or use the ref attribute to create an uncontrolled form.
A controlled form is a form where the input values are managed by the React component. To
create a controlled form, you can use the useState hook to create a state for each input and use
the value and onChange props of the input elements to control their values. Here is an example:
function App() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={event => setName(event.target.value)} />
</label>
<label>
Email:
<input type="email" value={email} onChange={event => setEmail(event.target.value)} />
</label>
<button type="submit">Submit</button>
</form>
);
}
handleSubmit function is called to prevent the default submission behavior and submit the form.
To implement server-side rendering in a Next.js application, you can use the getServerSideProps
method. This method is used to fetch data on the server-side and then pass it as props to the
component when rendering it on the server.
function Page(props) {
const router = useRouter();
const { id } = router.query;
const { data } = props;
In this example, the getServerSideProps method fetches data from an API using the id parameter
from the URL query, and then returns the data as props to the Page component. The Page
component then uses the data to render the page on the server.
To implement static site generation in a Next.js application, you can use the getStaticProps
method. This method is used to generate the HTML for a page at build time and then serve it
directly from the filesystem when a user requests the page.
function Page(props) {
const router = useRouter();
const { id } = router.query;
const { data } = props;
In this example, the getStaticProps method fetches data from an API using the id parameter from
the URL query, and then returns the data as props to the Page component. The Page component
then uses the data to render the page at build time, and the generated HTML is served from the
filesystem when a user requests the page.
To implement code splitting in a Next.js application, you can use the dynamic import syntax to
dynamically import and load a component only when it is needed. This allows you to split your
application into smaller chunks, which can be loaded on demand, improving the performance and
loading time of your application.
Here is an example of how to use the dynamic import syntax to implement code splitting in a
Next.js page component:
function Page() {
return (
<div>
<h1>My Page</h1>
<DynamicComponent />
</div>
);
}
the user navigates to the page. This can improve the performance and loading time of the
application.
To implement custom error pages in a Next.js application, you can create an _error.js file in the
pages directory. This file defines a component that will be used to render the error page when an
In this example, the Error component is used to render the error page. It receives the statusCode
of the error as props, and uses it to display a message about the error. The getInitialProps
method is used to fetch the statusCode from the server or client-side error object, and then pass it
as props to the component. When an error occurs in the application, the Error component will be
rendered with the appropriate statusCode to display a custom error message.
To implement environment variables in a Next.js application, you can create a .env file in the root
directory of your application. This file can be used to define environment-specific variables, such
as API keys or database connection strings, that are needed by the application.
To access the environment variables in your Next.js application, you can use the process.env
object, which contains the values of the environment variables defined in the .env file.
# .env
API_KEY=1234567890
DATABASE_URL=mongodb://localhost:27017/mydatabase
function Page() {
const router = useRouter();
const { id } = router.query;
// use the environment variables to fetch data from an API or connect to a database
// ...
// render the page using the data from the API or database
}
In this example, the .env file defines two environment variables: API_KEY and DATABASE_URL . These
variables are accessed using the process.env object in the Page component, and then used to
fetch data from an API or connect to a database. This allows the application to use different
values for the environment variables depending on the environment in which it is running.
To implement dynamic routes in a Next.js application, you can use the [id].js syntax in the pages
directory. This syntax allows you to define a route that contains a dynamic parameter, which can
be accessed in the page component using the useRouter hook.
function Page() {
const router = useRouter();
const { id } = router.query;
// fetch data from an API using the id from the URL query
// ...
In this example, the Page component is defined in a file named [id].js in the pages directory.
This means that the id parameter in the URL will be available in the component as a dynamic
parameter. The useRouter hook is used to access the id parameter from the URL query, and then
the component fetches data from an API using the id value. The page is then rendered using the
data from the API.
For example, if a user navigates to the /users/123 URL, the Page component will be rendered with
the id parameter set to 123 . This allows the component to fetch and display data for the user
with the id of 123 .
To implement serverless deployment of a Next.js application, you can use the next/serverless
module. This module provides a way to deploy a Next.js application as a serverless function,
which allows you to run your application in a cloud environment without having to manage any
servers.
To use the next/serverless module, you need to add it as a dependency in your Next.js application
and create a next.config.js file in the root directory of your application. This file defines the
configuration for the next/serverless module, including the entry point for the serverless function
and the cloud provider where the application will be deployed.
Here is an example of how to use the next/serverless module to deploy a Next.js application as a
serverless function:
// next.config.js
module.exports = {
target: 'serverless',
serverless: {
entry: 'server/server.js',
provider: {
name: 'aws',
runtime: 'nodejs12.x',
stage: 'dev',
region: 'us-east-1',
environment: {
API_KEY: '1234567890',
},
},
},
};
In this example, the next/serverless module is configured to use the server/server.js file as the
entry point for the serverless function, and to deploy the application to AWS using the nodejs12.x
To deploy the application, you can run the next build && next export commands to build and export
the static assets for the application, and then run the serverless deploy command to deploy the
application as a serverless function to the cloud provider defined in the configuration. The
next/serverless module will handle the deployment process, including creating and configuring the
necessary resources in the cloud provider, uploading the built assets and the serverless function
code, and setting up the routes and endpoints for the application.
To implement internationalization (i18n) in a Next.js application, you can use the next-i18next
library. This library provides a way to manage translations and locales in a Next.js application,
allowing you to easily support multiple languages and formats.
To use the next-i18next library, you need to add it as a dependency in your Next.js application and
create a i18n.js file in the root directory of your application. This file defines the configuration for
the next-i18next library, including the default language, the supported languages, and the
translation files for each language.
Here is an example of how to use the next-i18next library to implement internationalization in a
Next.js application:
// i18n.js
In this example, the next-i18next library is configured to use en as the default language, and to
support fr and de as additional languages. The localeSubpaths option is also defined to specify
the subpaths for each language in the URL, and the localePath option is defined to specify the
location of the translation files for each language.
To use the next-i18next library in a page component, you need to import the withTranslation
higher-order component (HOC) and use it to wrap the component. This HOC provides the t
To integrate a server-side backend, such as a REST API or GraphQL API, with a Next.js
application, you can use the isomorphic-unfetch library. This library provides a way to fetch data
from a server-side API in a Next.js application, allowing you to easily access and use the data in
your components.
To use the isomorphic-unfetch library, you need to add it as a dependency in your Next.js
application and import it in your page components. You can then use the fetch function provided
by the library to make HTTP requests to the API and fetch the data you need.
Here is an example of how to use the isomorphic-unfetch library to integrate a server-side API with
a Next.js application:
function Page() {
const router = useRouter();
const { id } = router.query;
In this example, the fetch function provided by the isomorphic-unfetch library is used to make a
HTTP request to the REST API and fetch the data for the page. The data is then returned as
JSON and can be used to render the page.
To integrate a GraphQL API with a Next.js application, you can use the apollo-client library and
the @apollo/react-hooks package. These libraries provide a way to query a GraphQL API and
manage the data in your components using React hooks.
Here is an example of how to use the apollo-client library and the @apollo/react-hooks package to
integrate a GraphQL API with a Next.js application:
function Page() {
const router = useRouter();
const { id } = router.query;
// fetch data from a GraphQL API using the apollo-client and @apollo/react-hooks libraries
const { data, loading, error } = useQuery(QUERY, {
variables: { id },
});
In this example, the apollo-client library is used to create an ApolloClient instance, which is
configured with the URL of the GraphQL API and an in-memory cache. The useQuery hook
provided by the @apollo/react-hooks package is then used to fetch the data from the API using a
GraphQL query. The data , loading , and error values returned by the hook can be used to render
the page and display the data from the API.