-
What is suspense component?
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.
For example, the below code uses suspense component,
const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> </div> ); }As mentioned in the above code, Suspense is wrapped above the lazy component.
-
What is route based code splitting?
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.
-
Give an example on How to use context?
Context is designed to share data that can be considered global for a tree of React components.
For example, in the code below lets manually thread through a “theme” prop in order to style the Button component.
//Lets create a context with a default theme value "luna" const ThemeContext = React.createContext('luna'); // Create App component where it uses provider to pass theme value in the tree class App extends React.Component { render() { return ( <ThemeContext.Provider value="nova"> <Toolbar /> </ThemeContext.Provider> ); } } // A middle component where you don't need to pass theme prop anymore function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } // Lets read theme value in the button component to use class ThemedButton extends React.Component { static contextType = ThemeContext; render() { return <Button theme={this.context} />; } } -
What is the purpose of default value in context?
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); -
How do you use contextType?
ContextType is used to consume the context object. The contextType property can be used in two ways,
-
contextType as property of class: The contextType property on a class can be assigned a Context object created by React.createContext(). After that, you can consume the nearest current value of that Context type using this.context in any of the lifecycle methods and render function.
Lets assign contextType property on MyClass as below,
class MyClass extends React.Component { componentDidMount() { let value = this.context; /* perform a side-effect at mount using the value of MyContext */ } componentDidUpdate() { let value = this.context; /* ... */ } componentWillUnmount() { let value = this.context; /* ... */ } render() { let value = this.context; /* render something based on the value of MyContext */ } } MyClass.contextType = MyContext; -
Static field You can use a static class field to initialize your contextType using public class field syntax.
class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; /* render something based on the value */ } }
-
-
What is a consumer?
A Consumer is a React component that subscribes to context changes. It requires a function as a child which receives current context value as argument and returns a react node. The value argument passed to the function will be equal to the value prop of the closest Provider for this context above in the tree.
Lets take a simple example,
<MyContext.Consumer> {value => /* render something based on the context value */} </MyContext.Consumer> -
How do you solve performance corner cases while using context?
The context uses reference identity to determine when to re-render, there are some gotchas that could trigger unintentional renders in consumers when a provider’s parent re-renders.
For example, the code below will re-render all consumers every time the Provider re-renders because a new object is always created for value.
class App extends React.Component { render() { return ( <Provider value={{something: 'something'}}> <Toolbar /> </Provider> ); } }This can be solved by lifting up the value to parent state,
class App extends React.Component { constructor(props) { super(props); this.state = { value: {something: 'something'}, }; } render() { return ( <Provider value={this.state.value}> <Toolbar /> </Provider> ); } } -
What is the purpose of forward ref in HOCs?
Refs will not get passed through because ref is not a prop. It handled differently by React just like key. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component. In this case, you can use Forward Ref API. For example, we can explicitly forward refs to the inner FancyButton component using the React.forwardRef API.
The below HOC logs all props,
function logProps(Component) { class LogProps extends React.Component { componentDidUpdate(prevProps) { console.log('old props:', prevProps); console.log('new props:', this.props); } render() { const {forwardedRef, ...rest} = this.props; // Assign the custom prop "forwardedRef" as a ref return <Component ref={forwardedRef} {...rest} />; } } return React.forwardRef((props, ref) => { return <LogProps {...props} forwardedRef={ref} />; }); }Let's use this HOC to log all props that get passed to our “fancy button” component,
class FancyButton extends React.Component { focus() { // ... } // ... } export default logProps(FancyButton);Now lets create a ref and pass it to FancyButton component. In this case, you can set focus to button element.
import FancyButton from './FancyButton'; const ref = React.createRef(); ref.current.focus(); <FancyButton label="Click Me" handleClick={handleClick} ref={ref} />; -
Is it ref argument available for all functions or class components?
Regular function or class components don’t receive the ref argument, and ref is not available in props either. The second ref argument only exists when you define a component with React.forwardRef call.
-
Why do you need additional care for component libraries while using forward refs?
When you start using forwardRef in a component library, you should treat it as a breaking change and release a new major version of your library. This is because your library likely has a different behavior such as what refs get assigned to, and what types are exported. These changes can break apps and other libraries that depend on the old behavior.