logo
eng-flag

React Cheatsheet

Table of Contents

  1. JSX Basics
  2. Components
  3. Props
  4. State
  5. Lifecycle Methods
  6. Hooks
  7. Event Handling
  8. Conditional Rendering
  9. Lists and Keys
  10. Forms
  11. Context API
  12. Refs
  13. Higher-Order Components (HOCs)
  14. Render Props
  15. Portals
  16. Error Boundaries
  17. Code Splitting
  18. Styling in React
  19. Performance Optimization
  20. Testing

JSX Basics

Basic Syntax

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

Embedding Expressions

const name = 'John';
const element = <h1>Hello, {name}</h1>;

Attributes

const element = <div className="container">Content</div>;

Children

const element = (
  <div>
    <h1>Title</h1>
    <p>Paragraph</p>
  </div>
);

Components

Functional Component

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Class Component

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Composing Components

function App() {
  return (
    <div>
      <Welcome name="Alice" />
      <Welcome name="Bob" />
    </div>
  );
}

Props

Passing Props

<Welcome name="Alice" age={25} />

Accessing Props

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Default Props

Welcome.defaultProps = {
  name: 'Guest'
};

PropTypes

import PropTypes from 'prop-types';

Welcome.propTypes = {
  name: PropTypes.string.isRequired
};

State

Class Component State

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return <div>Count: {this.state.count}</div>;
  }
}

Updating State

this.setState({ count: this.state.count + 1 });

Functional Updates

this.setState((prevState) => ({
  count: prevState.count + 1
}));

Lifecycle Methods

Mounting

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    // Initialize state
  }

  static getDerivedStateFromProps(props, state) {
    // Return new state based on props
  }

  render() {
    // Render component
  }

  componentDidMount() {
    // Component mounted
  }
}

Updating

class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Decide whether to re-render
  }

  render() {
    // Render component
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Capture information from the DOM
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // Component updated
  }
}

Unmounting

class MyComponent extends React.Component {
  componentWillUnmount() {
    // Clean up
  }
}

Hooks

useState

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

useEffect

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

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

useContext

import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Themed Button</button>;
}

useReducer

import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </>
  );
}

useCallback

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

function ParentComponent() {
  const [count, setCount] = useState(0);

  const incrementCount = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []);

  return <ChildComponent onIncrement={incrementCount} />;
}

useMemo

import React, { useMemo } from 'react';

function ExpensiveComponent({ a, b }) {
  const result = useMemo(() => {
    // Expensive computation
    return a + b;
  }, [a, b]);

  return <div>{result}</div>;
}

useRef

import React, { useRef } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

Event Handling

Handling Events

function handleClick() {
  console.log('Button clicked!');
}

return <button onClick={handleClick}>Click me</button>;

Passing Arguments to Event Handlers

function handleClick(id) {
  console.log('Clicked item with id:', id);
}

return <button onClick={() => handleClick(42)}>Click me</button>;

Conditional Rendering

If Statement

function Greeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

Ternary Operator

function Greeting({ isLoggedIn }) {
  return isLoggedIn ? <UserGreeting /> : <GuestGreeting />;
}

Logical && Operator

function Mailbox({ unreadMessages }) {
  return (
    <div>
      {unreadMessages.length > 0 &&
        <h2>You have {unreadMessages.length} unread messages.</h2>
      }
    </div>
  );
}

Lists and Keys

Rendering Lists

function NumberList({ numbers }) {
  return (
    <ul>
      {numbers.map((number) =>
        <li key={number.toString()}>{number}</li>
      )}
    </ul>
  );
}

Keys

const todoItems = todos.map((todo) =>
  <li key={todo.id}>{todo.text}</li>
);

Forms

Controlled Components

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: '' };
  }

  handleChange = (event) => {
    this.setState({ value: event.target.value });
  }

  handleSubmit = (event) => {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" value={this.state.value} onChange={this.handleChange} />
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

Uncontrolled Components

class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.fileInput = React.createRef();
  }

  handleSubmit = (event) => {
    event.preventDefault();
    alert(`Selected file - ${this.fileInput.current.files[0].name}`);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="file" ref={this.fileInput} />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

Context API

Creating Context

const ThemeContext = React.createContext('light');

Provider

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

Consumer

function ThemedButton() {
  return (
    <ThemeContext.Consumer>
      {theme => <button className={theme}>Themed Button</button>}
    </ThemeContext.Consumer>
  );
}

Refs

Creating Refs

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  render() {
    return <div ref={this.myRef} />;
  }
}

Accessing Refs

const node = this.myRef.current;

Higher-Order Components (HOCs)

HOC Definition

function withSubscription(WrappedComponent, selectData) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        data: selectData(DataSource, props)
      };
    }

    // ... implementation details

    render() {
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}

Using HOC

const CommentListWithSubscription = withSubscription(CommentList, (DataSource) => DataSource.getComments());

Render Props

Render Prop Component

class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

Using Render Prop

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

Portals

Creating a Portal

import ReactDOM from 'react-dom';

function Modal({ children }) {
  return ReactDOM.createPortal(
    children,
    document.getElementById('modal-root')
  );
}

Error Boundaries

Error Boundary Component

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

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

  componentDidCatch(error, errorInfo) {
    logErrorToMyService(error, errorInfo);
  }

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

    return this.props.children;
  }
}

Using Error Boundary

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

Code Splitting

Dynamic Import

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </Suspense>
  );
}

Styling in React

Inline Styles

function MyComponent() {
  return <div style={{ color: 'red', fontSize: '14px' }}>Styled text</div>;
}

CSS Modules

// styles.module.css
.myClass {
  color: blue;
  font-size: 16px;
}

// MyComponent.js
import styles from './styles.module.css';

function MyComponent() {
  return <div className={styles.myClass}>Styled text</div>;
}

Styled-components

import styled from 'styled-components';

const StyledButton = styled.button`
  background-color: blue;
  color: white;
  padding: 10px 20px;
`;

function MyComponent() {
  return <StyledButton>Click me</StyledButton>;
}

Performance Optimization

React.memo

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

Testing

Jest and React Testing Library

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import MyComponent from './MyComponent';

test('renders learn react link', () => {
  render(<MyComponent />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});

test('button click', async () => {
  render(<MyComponent />);
  const button = screen.getByRole('button', { name: /click me/i });
  await userEvent.click(button);
  expect(screen.getByText(/clicked/i)).toBeInTheDocument();
});

2024 © All rights reserved - buraxta.com