The most common interview question for the frontend developer post can be fetching the data from an API and rendering the elements.
Even though it seems a very simple task, there can be some improvements and optimisation that interviewer asks to do it while pair programming session.
The main purpose of this round is to check your understanding about different concepts. These are some of the questions that I have been asked by the interviewer.
- Declare the Types and interfaces
- Declare three states or a single state with both other states
- Handle Race condition
- Discuss What are the different ways to handle it
- AbortController
- UseRef
- Mounted vs Unmounted
- getDetails call
- Can you declare the custom Hook
- Why UseState and what If UseReducer
- Why not arrow functions for buttons and what purpose it serves
import { useEffect, useRef, useState } from "react"
type Users = {
name: string;
username: string;
email: string;
address: Address
id: number
}
type Address = {
street: string;
city: string;
}
export const DataTable = () => {
const [users, setUsers] = useState<Users[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const requestId = useRef(0)
const abortController = new AbortController();
const getUsers = async (elementId?: number) => {
setLoading(true)
const currentId = ++requestId.current;
try {
let response;
if (elementId) {
response = await fetch(`https://jsonplaceholder.typicode.com/users/${elementId}`, { signal: abortController.signal })
} else {
response = await fetch(`https://jsonplaceholder.typicode.com/users/`, { signal: abortController.signal })
}
if (!response.ok) {
throw new Error('Server side error')
};
const data = await response.json()
console.log(data)
if (currentId === requestId.current) {
if (!Array.isArray(data)) {
setUsers([data])
} else {
setUsers(data)
}
}
} catch (error) {
if (error instanceof Error) {
setError(error.message)
}
} finally {
setLoading(false)
console.log('Complete')
}
}
useEffect(() => {
getUsers()
return () => {
abortController.abort();
}
}, [])
const getDetails = (elementId: number) => {
getUsers(elementId)
}
const getAllUsers = () => {
getUsers();
}
return (<>
Hello DataTable <hr></hr>
<button onClick={getAllUsers}>Get All Users</button>
{error && <>{error}</>}
{loading ? <div>
loading...
</div> :
(<table>
<tbody>
<tr>
<th>Id</th>
<th>Name</th>
<th>Username</th>
<th>Get Details</th>
</tr>
{users.map((el: Users) => {
return (<tr key={el.id}>
<td>
{el.id}
</td>
<td>
{el.name}
</td>
<td>
{el.username}
</td>
<td>
{el.email}
</td>
<td>
<button onClick={() => getDetails(el.id)}>
Get Details
</button>
</td>
</tr>)
})}
</tbody>
</table>)
}
</>)
}
Declare the Types and interfaces
You can declare the relevant interfaces or types to apply the typescript data types to the respective useStates and wherever it is required.Declare three states or a single state with both other states.
This can be done by combining the all the three states in a single one.Handle Race condition
When multiple calls happen one after another but the response of the first request comes back after the second one then there can be a stale response. This can be handled in different ways, one of them is with useRef with a requestId as shown in the code.Discuss What are the different ways to handle it.
Abortcontroller
RequestId
Mounted vs Unmounted
AbortController
It cancels the request if the component is unmounted before the arrival of the response.UseRef
Mounted vs Unmounted
getDetails call
Can you declare the custom Hook
Why UseState and what If UseReducer
Why not arrow functions for buttons and what purpose it serves
So these are some of the questions that you can prepare yourself.
Top comments (0)