DEV Community

SOVANNARO
SOVANNARO

Posted on

20 Advanced React Techniques Every Senior Developer Should Master

React has become one of the most popular JavaScript libraries for building user interfaces, particularly single-page applications. As a senior developer, mastering advanced React techniques is crucial for creating efficient, scalable, and maintainable applications. This article delves into 20 advanced React techniques that every senior developer should know, complete with TypeScript examples where applicable.

1. Higher-Order Components (HOCs)

Higher-Order Components are a pattern in React for reusing component logic. An HOC is a function that takes a component and returns a new component.

import React from 'react';

const withLogger = (WrappedComponent: React.ComponentType) => {
  return class extends React.Component {
    componentDidMount() {
      console.log(`Component ${WrappedComponent.name} mounted`);
    }
    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

const MyComponent: React.FC = () => <div>Hello World</div>;
const MyComponentWithLogger = withLogger(MyComponent);
Enter fullscreen mode Exit fullscreen mode

2. Render Props

Render props are a technique for sharing code between React components using a prop whose value is a function.

import React from 'react';

interface DataFetcherProps {
  render: (data: any) => JSX.Element;
}

const DataFetcher: React.FC<DataFetcherProps> = ({ render }) => {
  const data = { name: 'John Doe' };
  return render(data);
};

const MyComponent: React.FC = () => (
  <DataFetcher render={(data) => <div>{data.name}</div>} />
);
Enter fullscreen mode Exit fullscreen mode

3. Context API

The Context API is a React structure that enables you to exchange unique details and assists in solving prop-drilling from the top parent component to children.

import React, { createContext, useContext } from 'react';

const MyContext = createContext<string | null>(null);

const MyProvider: React.FC = ({ children }) => {
  const value = 'Hello from Context';
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
};

const MyComponent: React.FC = () => {
  const value = useContext(MyContext);
  return <div>{value}</div>;
};
Enter fullscreen mode Exit fullscreen mode

4. Custom Hooks

Custom hooks allow you to encapsulate and reuse stateful logic.

import { useState, useEffect } from 'react';

const useFetch = (url: string) => {
  const [data, setData] = useState<any>(null);
  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => setData(data));
  }, [url]);
  return data;
};

const MyComponent: React.FC = () => {
  const data = useFetch('https://api.example.com/data');
  return <div>{data ? data.name : 'Loading...'}</div>;
};
Enter fullscreen mode Exit fullscreen mode

5. Error Boundaries

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI.

import React from 'react';

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error: any) {
    return { hasError: true };
  }

  componentDidCatch(error: any, errorInfo: any) {
    console.log(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

const MyComponent: React.FC = () => {
  throw new Error('Test error');
  return <div>Hello World</div>;
};

const App: React.FC = () => (
  <ErrorBoundary>
    <MyComponent />
  </ErrorBoundary>
);
Enter fullscreen mode Exit fullscreen mode

6. Code Splitting

Code splitting is a feature supported by bundlers like Webpack, Rollup, and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime.

import React, { lazy, Suspense } from 'react';

const LazyComponent = lazy(() => import('./LazyComponent'));

const MyComponent: React.FC = () => (
  <Suspense fallback={<div>Loading...</div>}>
    <LazyComponent />
  </Suspense>
);
Enter fullscreen mode Exit fullscreen mode

7. Memoization

Memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

import React, { useMemo } from 'react';

const MyComponent: React.FC<{ items: number[] }> = ({ items }) => {
  const sortedItems = useMemo(() => items.sort(), [items]);
  return <div>{sortedItems.join(', ')}</div>;
};
Enter fullscreen mode Exit fullscreen mode

8. Portals

Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

import React from 'react';
import ReactDOM from 'react-dom';

const MyPortal: React.FC = () => {
  return ReactDOM.createPortal(
    <div>This is rendered in a portal</div>,
    document.getElementById('portal-root')!
  );
};
Enter fullscreen mode Exit fullscreen mode

9. Fragments

Fragments let you group a list of children without adding extra nodes to the DOM.

import React, { Fragment } from 'react';

const MyComponent: React.FC = () => (
  <Fragment>
    <div>Item 1</div>
    <div>Item 2</div>
  </Fragment>
);
Enter fullscreen mode Exit fullscreen mode

10. Refs and the DOM

Refs provide a way to access DOM nodes or React elements created in the render method.

import React, { useRef, useEffect } from 'react';

const MyComponent: React.FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} type="text" />;
};
Enter fullscreen mode Exit fullscreen mode

11. Forwarding Refs

Ref forwarding is a technique for automatically passing a ref through a component to one of its children.

import React, { forwardRef, useRef } from 'react';

const MyInput = forwardRef<HTMLInputElement, {}>((props, ref) => (
  <input ref={ref} type="text" />
));

const MyComponent: React.FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);

  return <MyInput ref={inputRef} />;
};
Enter fullscreen mode Exit fullscreen mode

12. Controlled and Uncontrolled Components

Controlled components have their state and behavior controlled by the parent component, while uncontrolled components manage their own state.

import React, { useState } from 'react';

const ControlledComponent: React.FC = () => {
  const [value, setValue] = useState('');
  return <input value={value} onChange={(e) => setValue(e.target.value)} />;
};

const UncontrolledComponent: React.FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);
  return <input ref={inputRef} type="text" />;
};
Enter fullscreen mode Exit fullscreen mode

13. Performance Optimization

Performance optimization techniques include using React.memo, useMemo, and useCallback to prevent unnecessary re-renders.

import React, { useCallback, memo } from 'react';

const MyComponent: React.FC<{ onClick: () => void }> = memo(({ onClick }) => {
  console.log('Rendering MyComponent');
  return <button onClick={onClick}>Click me</button>;
});

const ParentComponent: React.FC = () => {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []);

  return <MyComponent onClick={handleClick} />;
};
Enter fullscreen mode Exit fullscreen mode

14. Server-Side Rendering (SSR)

Server-Side Rendering is a technique used to render a normally client-side only single-page application (SPA) on the server and then send a fully rendered page to the client.

import React from 'react';
import { renderToString } from 'react-dom/server';

const MyComponent: React.FC = () => <div>Hello World</div>;

const html = renderToString(<MyComponent />);
Enter fullscreen mode Exit fullscreen mode

15. Static Site Generation (SSG)

Static Site Generation is a technique used to pre-render pages at build time.

import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server';

const MyComponent: React.FC = () => <div>Hello World</div>;

const html = renderToStaticMarkup(<MyComponent />);
Enter fullscreen mode Exit fullscreen mode

16. Incremental Static Regeneration (ISR)

Incremental Static Regeneration allows you to update static content after you’ve built your site.

import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server';

const MyComponent: React.FC = () => <div>Hello World</div>;

const html = renderToStaticMarkup(<MyComponent />);
Enter fullscreen mode Exit fullscreen mode

17. Concurrent Mode

Concurrent Mode is a set of new features that help React apps stay responsive and gracefully adjust to the user's device capabilities and network speed.

import React, { useState, useTransition } from 'react';

const MyComponent: React.FC = () => {
  const [isPending, startTransition] = useTransition();
  const [count, setCount] = useState(0);

  const handleClick = () => {
    startTransition(() => {
      setCount(count + 1);
    });
  };

  return (
    <div>
      <button onClick={handleClick}>Increment</button>
      {isPending ? 'Loading...' : `Count: ${count}`}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

18. Suspense for Data Fetching

Suspense for Data Fetching allows you to wait for some code to load and declaratively specify a loading state (like a spinner) for it.

import React, { Suspense } from 'react';

const MyComponent: React.FC = () => {
  const data = fetchData();
  return <div>{data.name}</div>;
};

const App: React.FC = () => (
  <Suspense fallback={<div>Loading...</div>}>
    <MyComponent />
  </Suspense>
);
Enter fullscreen mode Exit fullscreen mode

19. React Query

React Query is a powerful data-fetching library for React that makes it easy to fetch, cache, synchronize, and update server state in your React applications.

import React from 'react';
import { useQuery } from 'react-query';

const fetchData = async () => {
  const response = await fetch('https://api.example.com/data');
  return response.json();
};

const MyComponent: React.FC = () => {
  const { data, error, isLoading } = useQuery('data', fetchData);

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return <div>{data.name}</div>;
};
Enter fullscreen mode Exit fullscreen mode

20. React Server Components

React Server Components allow you to build apps that span the client and server, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering.

import React from 'react';

const MyServerComponent: React.FC = () => {
  const data = fetchDataFromServer();
  return <div>{data.name}</div>;
};

const MyClientComponent: React.FC = () => {
  return <MyServerComponent />;
};
Enter fullscreen mode Exit fullscreen mode

Conclusion

Mastering these 20 advanced React techniques will significantly enhance your ability to build robust, efficient, and maintainable React applications. Whether you're optimizing performance, managing state, or leveraging server-side rendering, these techniques provide a comprehensive toolkit for senior React developers. By incorporating these practices into your development workflow, you'll be well-equipped to tackle complex challenges and deliver high-quality applications.

Top comments (0)