FrontendDeveloper.in

React Interview Questions

Filter by topic:
  • Formik is a form library for react which provides solutions such as validation, keeping track of the visited fields, and handling form submission.

    In detail, You can categorize them as follows,

    1. Getting values in and out of form state
    2. Validation and error messages
    3. Handling form submission

    It is used to create a scalable, performant, form helper with a minimal API to solve annoying stuff.

  • Below are the main reasons to recommend formik over redux form library,

    1. The form state is inherently short-term and local, so tracking it in Redux (or any kind of Flux library) is unnecessary.
    2. Redux-Form calls your entire top-level Redux reducer multiple times ON EVERY SINGLE KEYSTROKE. This way it increases input latency for large apps.
    3. Redux-Form is 22.5 kB minified gzipped whereas Formik is 12.7 kB
  • In React, it is recommended to use composition over inheritance to reuse code between components. Both Props and composition give you all the flexibility you need to customize a component’s look and behavior explicitly and safely. Whereas, If you want to reuse non-UI functionality between components, it is suggested to extract it into a separate JavaScript module. Later components import it and use that function, object, or class, without extending it.

  • Yes, you can use web components in a react application. Even though many developers won't use this combination, it may require especially if you are using third-party UI components that are written using Web Components.

    For example, let us use Vaadin date picker web component as below,

    import "./App.css";
    import "@vaadin/vaadin-date-picker";
    export default function App() {
    return (
    <vaadin-date-picker label="When were you born?"></vaadin-date-picker>
    );
    }
    
  • You can achieve code-splitting in your app using dynamic import.

    Let's take an example of addition,

    1. Normal Import
    import { add } from "./math";
    console.log(add(10, 20));
    
    1. Dynamic Import
    import("./math").then((math) => {
    console.log(math.add(10, 20));
    });
    
  • With the release of React 18, React.lazy and Suspense are now available for server-side rendering. However, prior to React 18, it was recommended to use Loadable Components for code-splitting in a server-side rendered app because React.lazy and Suspense were not available for server-side rendering. Loadable Components lets you render a dynamic import as a regular component. For example, you can use Loadable Components to load the OtherComponent in a separate bundle like this:

    import loadable from "@loadable/component";
    
    const OtherComponent = loadable(() => import("./OtherComponent"));
    
    function MyComponent() {
    return (
    <OtherComponent />
    );
    }
    

    Now OtherComponent will be loaded in a separated bundle Loadable Components provides additional benefits beyond just code-splitting, such as automatic code reloading, error handling, and preloading. By using Loadable Components, you can ensure that your application loads quickly and efficiently, providing a better user experience for your users.

  • React Suspense is a built-in feature that lets you defer rendering part of your component tree until some condition(asynchronous operation) is met—usually, data or code has finished loading. While waiting, Suspense lets you display a fallback UI like a spinner or placeholder.

    1. Lazy loading components uses suspense feature,

    If the module containing the dynamic import is not yet loaded by the time parent component renders, you must show some fallback content while you’re waiting for it to load using a loading indicator. This can be done using Suspense component.

    const OtherComponent = React.lazy(() => import("./OtherComponent"));
    
    function MyComponent() {
    return (
    <Suspense fallback={<div>Loading...</div>}>
    <OtherComponent />
    </Suspense>
    );
    }
    

    The above component shows fallback UI instead real component until OtherComponent is fully loaded.

    1. As an another example, suspend until async data(data fetching) is ready
    function UserProfile() {
    const user = use(fetchUser()); // throws a promise internally
    return <div>{user.name}</div>;
    }
    
    function App() {
    return (
    <Suspense fallback={<div>Loading user...</div>}>
    <UserProfile />
    </Suspense>
    );
    }
    
    
  • One of the best place to do code splitting is with routes. The entire page is going to re-render at once so users are unlikely to interact with other elements in the page at the same time. Due to this, the user experience won't be disturbed.

    Let us take an example of route based website using libraries like React Router with React.lazy,

    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    import React, { Suspense, lazy } from "react";
    
    const Home = lazy(() => import("./routes/Home"));
    const About = lazy(() => import("./routes/About"));
    
    const App = () => (
    <Router>
    <Suspense fallback={<div>Loading...</div>}>
    <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/about" component={About} />
    </Switch>
    </Suspense>
    </Router>
    );
    

    In the above code, the code splitting will happen at each route level.

  • The defaultValue argument is only used when a component does not have a matching Provider above it in the tree. This can be helpful for testing components in isolation without wrapping them.

    Below code snippet provides default theme value as Luna.

    const MyContext = React.createContext(defaultValue);
    
  • React needs to use algorithms to find out how to efficiently update the UI to match the most recent tree. The diffing algorithms is generating the minimum number of operations to transform one tree into another. However, the algorithms have a complexity in the order of O(n³) where n is the number of elements in the tree.

    In this case, displaying 1000 elements would require in the order of one billion comparisons. This is far too expensive. Instead, React implements a heuristic O(n) algorithm based on two assumptions:

    1. Two elements of different types will produce different trees.
    2. The developer can hint at which child elements may be stable across different renders with a key prop.
  • When diffing two trees, React first compares the two root elements. The behavior is different depending on the types of the root elements. It covers the below rules during reconciliation algorithm,

    1. Elements Of Different Types: Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. For example, elements <a> to <img>, or from <Article> to <Comment> of different types lead a full rebuild.
    2. DOM Elements Of The Same Type: When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes. Lets take an example with same DOM elements except className attribute,
    1. Component Elements Of The Same Type: When a component updates, the instance stays the same, so that state is maintained across renders. React updates the props of the underlying component instance to match the new element, and calls componentWillReceiveProps() and componentWillUpdate() on the underlying instance. After that, the render() method is called and the diff algorithm recurses on the previous result and the new result.
    2. Recursing On Children: when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there’s a difference. For example, when adding an element at the end of the children, converting between these two trees works well.
    <ul>
    <li>first</li>
    <li>second</li>
    </ul>
    
    <ul>
    <li>first</li>
    <li>second</li>
    <li>third</li>
    </ul>
    
    
    1. Handling keys: React supports a key attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree. For example, adding a key can make the tree conversion efficient,
    <ul>
    <li key="2015">Duke</li>
    <li key="2016">Villanova</li>
    </ul>
    
    <ul>
    <li key="2014">Connecticut</li>
    <li key="2015">Duke</li>
    <li key="2016">Villanova</li>
    </ul>
    
  • There are few use cases to go for refs,

    1. Managing focus, text selection, or media playback.
    2. Triggering imperative animations.
    3. Integrating with third-party DOM libraries.
  • Even though the pattern named render props, you don’t have to use a prop named render to use this pattern. i.e, Any prop that is a function that a component uses to know what to render is technically a “render prop”. Lets take an example with the children prop for render props,

    <Mouse
    children={(mouse) => (
    The mouse position is {mouse.x}, {mouse.y}
    )}
    />
    

    Actually children prop doesn’t need to be named in the list of “attributes” in JSX element. Instead, you can keep it directly inside element,

    <Mouse>
    {(mouse) => (
    The mouse position is {mouse.x}, {mouse.y}
    )}
    </Mouse>
    

    While using this above technique(without any name), explicitly state that children should be a function in your propTypes.

    Mouse.propTypes = {
    children: PropTypes.func.isRequired,
    };
    
  • If you create a function inside a render method, it negates the purpose of pure component. Because the shallow prop comparison will always return false for new props, and each render in this case will generate a new value for the render prop. You can solve this issue by defining the render function as instance method.

  • Windowing is a technique that only renders a small subset of your rows at any given time, and can dramatically reduce the time it takes to re-render the components as well as the number of DOM nodes created. If your application renders long lists of data then this technique is recommended. Both react-window and react-virtualized are popular windowing libraries which provides several reusable components for displaying lists, grids, and tabular data.