Cheat Sheet

ReactJS Cheat Sheet


1. Create a New React App


npx create-react-app my-app

2. Import React


import React from 'react';

3. Create a React Component


function MyComponent() {
  return <h1>Hello, World!</h1>;
}

4. Use JSX


const element = <h1>Hello, World!</h1>;

5. Use React Hooks


import { useState } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

6. Use React Context


import { createContext, useContext } from 'react';
const ThemeContext = createContext();
function MyComponent() {
  const theme = useContext(ThemeContext);
  return <div style={{ backgroundColor: theme.backgroundColor }}></div>;
}

7. Use React Router


import { BrowserRouter, Route, Link } from 'react-router-dom';
function MyComponent() {
  return (
    <BrowserRouter>
      <div>
        <h1>Home</h1>
        <p>
          <Link to=`/about`>About</Link>
        </p>
      </div>
      <Route path=`/about` component={About} />
    </BrowserRouter>
  );
}

8. Use React Redux


import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
const store = createStore(reducer);
function MyComponent() {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
    </div>
  );
}

9. Use React Hooks for State Management


import { useState, useEffect } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

10. Use React Hooks for Side Effects


import { useEffect } from 'react';
function MyComponent() {
  useEffect(() => {
    console.log('Component mounted');
    return () => {
      console.log('Component unmounted');
    };
  }, []);
  return <div>Hello, World!</div>;
}

11. Use React Hooks for Context


import { useContext, useState } from 'react';
const ThemeContext = createContext();
function MyComponent() {
  const theme = useContext(ThemeContext);
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

12. Use React Hooks for Reducers


import { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

13. Use React Hooks for Memoization


import { useMemo } from 'react';
function MyComponent({ items }) {
  const sortedItems = useMemo(() => {
    return items.sort();
  }, [items]);
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

14. Use React Fragments


function MyComponent() {
  return (
    <>
      <h1>Title</h1>
      <p>Description</p>
    </>
  );
}

15. Use PropTypes for Type Checking


import PropTypes from 'prop-types';
function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
}
MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

16. Use Default Props


function MyComponent({ name = 'Guest' }) {
  return <h1>Hello, {name}!</h1>;
}

17. Use Higher-Order Components (HOC)


function withLogging(WrappedComponent) {
  return function EnhancedComponent(props) {
    console.log('Rendering:', props);
    return <WrappedComponent {...props} />;
  };
}

18. Use Render Props


function DataProvider({ render }) {
  const data = fetchData();
  return render(data);
}
function MyComponent() {
  return (
    <DataProvider render={data => <div>{data}</div>} />
  );
}

19. Use React.memo for Performance Optimization


const MyComponent = React.memo(function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
});

20. Use useRef for Accessing DOM Elements


import { useRef } from 'react';
function MyComponent() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    inputRef.current.focus();
  };
  return (
    <div>
      <input ref={inputRef} type=`text` />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

21. Use useLayoutEffect for Synchronous Effects


import { useLayoutEffect } from 'react';
function MyComponent() {
  useLayoutEffect(() => {
    // Synchronous effect
  }, []);
  return <div>Hello, World!</div>;
}

22. Use useImperativeHandle for Custom Ref


import { useImperativeHandle, forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

23. Use useDebugValue for Custom Hooks


import { useDebugValue } from 'react';
function useCustomHook(value) {
  useDebugValue(value ? 'Value is set' : 'Value is not set');
  return value;
}

24. Use useCallback for Memoizing Functions


import { useCallback } from 'react';
function MyComponent() {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []);
  
  return <button onClick={handleClick}>Click Me</button>;
}

25. Use useEffect for Data Fetching


import { useEffect, useState } from 'react';
function MyComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);
  
  return <div>{data}</div>;
}

26. Use useState for Local State Management


import { useState } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

27. Use useReducer for Complex State Management


import { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

28. Use useContext for Global State Management


import { createContext, useContext } from 'react';
const MyContext = createContext();
function MyProvider({ children }) {
  const value = { /* context value */ };
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
}
function MyComponent() {
  const context = useContext(MyContext);
  return <div>{context.value}</div>;
}

29. Use useMemo for Performance Optimization


import { useMemo } from 'react';
function MyComponent({ items }) {
  const sortedItems = useMemo(() => {
    return items.sort();
  }, [items]);
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

30. Use useEffect for Cleanup


import { useEffect } from 'react';
function MyComponent() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);
    
    return () => clearInterval(timer);
  }, []);
  
  return <div>Timer is running</div>;
}

31. Use useRef for Storing Mutable Values


import { useRef } from 'react';
function MyComponent() {
  const countRef = useRef(0);
  
  const increment = () => {
    countRef.current += 1;
    console.log(countRef.current);
  };
  return <button onClick={increment}>Increment</button>;
}

32. Use useImperativeHandle for Custom Hooks


import { useImperativeHandle, forwardRef, useRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

33. Use Error Boundaries for Error Handling


import React, { Component } from 'react';
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

34. Use React.StrictMode for Highlighting Potential Problems


<React.StrictMode>
  <MyComponent />
</React.StrictMode>

35. Use React.lazy for Code Splitting


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

36. Use PropTypes for Type Checking


import PropTypes from 'prop-types';
function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
}
MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

37. Use Default Props


function MyComponent({ name = 'Guest' }) {
  return <h1>Hello, {name}!</h1>;
}

38. Use Higher-Order Components (HOC)


function withLogging(WrappedComponent) {
  return function EnhancedComponent(props) {
    console.log('Rendering:', props);
    return <WrappedComponent {...props} />;
  };
}

39. Use Render Props


function DataProvider({ render }) {
  const data = fetchData();
  return render(data);
}
function MyComponent() {
  return (
    <DataProvider render={data => <div>{data}</div>} />
  );
}

40. Use React.memo for Performance Optimization


const MyComponent = React.memo(function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
});

41. Use useRef for Accessing DOM Elements


import { useRef } from 'react';
function MyComponent() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    inputRef.current.focus();
  };
  return (
    <div>
      <input ref={inputRef} type=`text` />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

42. Use useLayoutEffect for Synchronous Effects


import { useLayoutEffect } from 'react';
function MyComponent() {
  useLayoutEffect(() => {
    // Synchronous effect
  }, []);
  return <div>Hello, World!</div>;
}

43. Use useImperativeHandle for Custom Ref


import { useImperativeHandle, forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

44. Use useDebugValue for Custom Hooks


import { useDebugValue } from 'react';
function useCustomHook(value) {
  useDebugValue(value ? 'Value is set' : 'Value is not set');
  return value;
}

45. Use useCallback for Memoizing Functions


import { useCallback } from 'react';
function MyComponent() {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []);
  
  return <button onClick={handleClick}>Click Me</button>;
}

46. Use useEffect for Data Fetching


import { useEffect, useState } from 'react';
function MyComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);
  
  return <div>{data}</div>;
}

47. Use useState for Local State Management


import { useState } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

48. Use useReducer for Complex State Management


import { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

49. Use useContext for Global State Management


import { createContext, useContext } from 'react';
const MyContext = createContext();
function MyProvider({ children }) {
  const value = { /* context value */ };
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
}
function MyComponent() {
  const context = useContext(MyContext);
  return <div>{context.value}</div>;
}

50. Use useMemo for Performance Optimization


import { useMemo } from 'react';
function MyComponent({ items }) {
  const sortedItems = useMemo(() => {
    return items.sort();
  }, [items]);
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

51. Use useEffect for Cleanup


import { useEffect } from 'react';
function MyComponent() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);
    
    return () => clearInterval(timer);
  }, []);
  
  return <div>Timer is running</div>;
}

52. Use useRef for Storing Mutable Values


import { useRef } from 'react';
function MyComponent() {
  const countRef = useRef(0);
  
  const increment = () => {
    countRef.current += 1;
    console.log(countRef.current);
  };
  return <button onClick={increment}>Increment</button>;
}

53. Use useImperativeHandle for Custom Hooks


import { useImperativeHandle, forwardRef, useRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

54. Use Error Boundaries for Error Handling


import React, { Component } from 'react';
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

55. Use React.StrictMode for Highlighting Potential Problems


<React.StrictMode>
  <MyComponent />
</React.StrictMode>

56. Use React.lazy for Code Splitting


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

57. Use PropTypes for Type Checking


import PropTypes from 'prop-types';
function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
}
MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

58. Use Default Props


function MyComponent({ name = 'Guest' }) {
  return <h1>Hello, {name}!</h1>;
}

59. Use Higher-Order Components (HOC)


function withLogging(WrappedComponent) {
  return function EnhancedComponent(props) {
    console.log('Rendering:', props);
    return <WrappedComponent {...props} />;
  };
}

60. Use Render Props


function DataProvider({ render }) {
  const data = fetchData();
  return render(data);
}
function MyComponent() {
  return (
    <DataProvider render={data => <div>{data}</div>} />
  );
}

61. Use React.memo for Performance Optimization


const MyComponent = React.memo(function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
});

62. Use useRef for Accessing DOM Elements


import { useRef } from 'react';
function MyComponent() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    inputRef.current.focus();
  };
  return (
    <div>
      <input ref={inputRef} type=`text` />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

63. Use useLayoutEffect for Synchronous Effects


import { useLayoutEffect } from 'react';
function MyComponent() {
  useLayoutEffect(() => {
    // Synchronous effect
  }, []);
  return <div>Hello, World!</div>;
}

64. Use useImperativeHandle for Custom Ref


import { useImperativeHandle, forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

65. Use useDebugValue for Custom Hooks


import { useDebugValue } from 'react';
function useCustomHook(value) {
  useDebugValue(value ? 'Value is set' : 'Value is not set');
  return value;
}

66. Use useCallback for Memoizing Functions


import { useCallback } from 'react';
function MyComponent() {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []);
  
  return <button onClick={handleClick}>Click Me</button>;
}

67. Use useEffect for Data Fetching


import { useEffect, useState } from 'react';
function MyComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);
  
  return <div>{data}</div>;
}

68. Use useState for Local State Management


import { useState } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

69. Use useReducer for Complex State Management


import { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

70. Use useContext for Global State Management


import { createContext, useContext } from 'react';
const MyContext = createContext();
function MyProvider({ children }) {
  const value = { /* context value */ };
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
}
function MyComponent() {
  const context = useContext(MyContext);
  return <div>{context.value}</div>;
}

71. Use useMemo for Performance Optimization


import { useMemo } from 'react';
function MyComponent({ items }) {
  const sortedItems = useMemo(() => {
    return items.sort();
  }, [items]);
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

72. Use useEffect for Cleanup


import { useEffect } from 'react';
function MyComponent() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);
    
    return () => clearInterval(timer);
  }, []);
  
  return <div>Timer is running</div>;
}

73. Use useRef for Storing Mutable Values


import { useRef } from 'react';
function MyComponent() {
  const countRef = useRef(0);
  
  const increment = () => {
    countRef.current += 1;
    console.log(countRef.current);
  };
  return <button onClick={increment}>Increment</button>;
}

74. Use useImperativeHandle for Custom Hooks


import { useImperativeHandle, forwardRef, useRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

75. Use Error Boundaries for Error Handling


import React, { Component } from 'react';
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

76. Use React.StrictMode for Highlighting Potential Problems


<React.StrictMode>
  <MyComponent />
</React.StrictMode>

77. Use React.lazy for Code Splitting


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

78. Use PropTypes for Type Checking


import PropTypes from 'prop-types';
function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
}
MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

79. Use Default Props


function MyComponent({ name = 'Guest' }) {
  return <h1>Hello, {name}!</h1>;
}

80. Use Higher-Order Components (HOC)


function withLogging(WrappedComponent) {
  return function EnhancedComponent(props) {
    console.log('Rendering:', props);
    return <WrappedComponent {...props} />;
  };
}

81. Use Render Props


function DataProvider({ render }) {
  const data = fetchData();
  return render(data);
}
function MyComponent() {
  return (
    <DataProvider render={data => <div>{data}</div>} />
  );
}

82. Use React.memo for Performance Optimization


const MyComponent = React.memo(function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
});

83. Use useRef for Accessing DOM Elements


import { useRef } from 'react';
function MyComponent() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    inputRef.current.focus();
  };
  return (
    <div>
      <input ref={inputRef} type=`text` />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

84. Use useLayoutEffect for Synchronous Effects


import { useLayoutEffect } from 'react';
function MyComponent() {
  useLayoutEffect(() => {
    // Synchronous effect
  }, []);
  return <div>Hello, World!</div>;
}

85. Use useImperativeHandle for Custom Ref


import { useImperativeHandle, forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));
  return <input ref={inputRef} type=`text` />;
});

86. Use useDebugValue for Custom Hooks


import { useDebugValue } from 'react';
function useCustomHook(value) {
  useDebugValue(value ? 'Value is set' : 'Value is not set');
  return value;
}

87. Use useCallback for Memoizing Functions


import { useCallback } from 'react';
function MyComponent() {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []);
  
  return <button onClick={handleClick}>Click Me</button>;
}

88. Use useEffect for Data Fetching


import { useEffect, useState } from 'react';
function MyComponent() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);
  
  return <div>{data}</div>;
}

89. Use useState for Local State Management


import { useState } from 'react';
function MyComponent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

90. Use useReducer for Complex State Management


import { useReducer } from 'react';
const initialState = { count: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};
function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

91. Use useContext for Global State Management


import { createContext, useContext } from 'react';
const MyContext = createContext();
function MyProvider({ children }) {
  const value = { /* context value */ };
  return <MyContext.Provider value={value}>{children}</MyContext.Provider>;
}
function MyComponent() {
  const context = useContext(MyContext);
  return <div>{context.value}</div>;
}

92. Use useMemo for Performance Optimization


import { useMemo } from 'react';
function MyComponent({ items }) {
  const sortedItems = useMemo(() => {
    return items.sort();
  }, [items]);
  return (
    <ul>
      {sortedItems.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

93. Use useEffect for Cleanup


import { useEffect } from 'react';
function MyComponent() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);
    
    return () => clearInterval(timer);
  }, []);
  
  return <div>Timer is running</div>;
}

94. Use useRef for Storing Mutable Values


import { useRef } from 'react';
function MyComponent() {
  const countRef = useRef(0);
  
  const increment = () => {
    countRef.current += 1;
    console.log(countRef.current);
  };
  return <button onClick={increment}>Increment</button>;
}

95. Use useImperativeHandle for Custom Hooks


import { useImperativeHandle, forwardRef, useRef } from 'react';
const MyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
 }));
  return <input ref={inputRef} type=`text` />;
});

96. Use Error Boundaries for Error Handling


import React, { Component } from 'react';
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }
  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo);
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children; 
  }
}

97. Use React.StrictMode for Highlighting Potential Problems


<React.StrictMode>
  <MyComponent />
</React.StrictMode>

98. Use React.lazy for Code Splitting


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

99. Use PropTypes for Type Checking


import PropTypes from 'prop-types';
function MyComponent({ name }) {
  return <h1>Hello, {name}!</h1>;
}
MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
};

100. Use Default Props


function MyComponent({ name = 'Guest' }) {
  return <h1>Hello, {name}!</h1>;
}

Written by Surfside Media

Senior Full Stack Developer specializing in Web Technologies.