DEV Community

Ajinkya Chanshetty
Ajinkya Chanshetty

Posted on

Coding Challenges in React Interview for JPMC and Barclays Part 1

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.

  1. Declare the Types and interfaces
  2. Declare three states or a single state with both other states
  3. Handle Race condition
  4. Discuss What are the different ways to handle it
  5. AbortController
  6. UseRef
  7. Mounted vs Unmounted
  8. getDetails call
  9. Can you declare the custom Hook
  10. Why UseState and what If UseReducer
  11. 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>)
        }
    </>)

}
Enter fullscreen mode Exit fullscreen mode
  1. 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.

  2. 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.

  3. 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.

  4. Discuss What are the different ways to handle it.

  5. Abortcontroller

  6. RequestId

  7. Mounted vs Unmounted

  8. AbortController
    It cancels the request if the component is unmounted before the arrival of the response.

  9. UseRef
    This can be used to declare the requestId and every call will have a local currentRequestId to compare with this one.
    The new call will increment it and by comparing the values we can eliminate the race condition.

  10. Mounted vs Unmounted
    This is the least possible approach to avoid the race condition as the call restriction can be only avoided when the component is removed from the DOM.

  11. getDetails: This call can be reused for the getDetails by Id param.

  12. Can you declare the custom Hook: Yes, this can be declared as a custom hook to make this implementation scalable.

  13. Why UseState and what If UseReducer
    As we have a small state to manage and the same logic is still not shared with other components, I believe the useState can be the right choice here.

  14. Why not arrow functions for buttons and what purpose it serves?
    Whenever you call the functions with an added arrow notation in the button call then it creates a new copy of the same function for every render.

So these are some of the questions that you can prepare yourself.

Top comments (0)