React must know concepts - rs-hash/Learning GitHub Wiki

As a developer working with React, it's important to have a deep understanding of the following key concepts and features:

  1. Components:

    • Class Components: Class components are ES6 classes that extend the React.Component class. They have additional features like state management and lifecycle methods.
    • Functional Components: Functional components are JavaScript functions that return JSX (JavaScript XML). They are simpler, lightweight, and promote the use of React Hooks for state and lifecycle features.
  2. JSX:

    • JSX Syntax: JSX allows you to write HTML-like code directly within JavaScript. It gets transformed into regular JavaScript function calls and provides a declarative way to define the structure and appearance of components.
  3. Props:

    • Prop Types: PropTypes enable type-checking of props to ensure their correct usage and prevent potential bugs. They define the expected types and shape of props passed to a component.
    • Default Props: Default props provide fallback values for props in case they are not explicitly provided. Certainly! Here are code examples illustrating the concepts you mentioned:

Props:

Prop Types and Default Props:

Let's assume you have a Person component that receives name (string) and age (number) props. You can use PropTypes for type-checking and provide default props.

import React from 'react';
import PropTypes from 'prop-types';

const Person = ({ name, age }) => {
  return (
    <div>
      <p>Name: {name}</p>
      <p>Age: {age}</p>
    </div>
  );
};

Person.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
};

Person.defaultProps = {
  age: 18, // Default age if not provided
};

export default Person;
  1. State and Lifecycle:
    • State: State allows components to have internal data that can change over time. It is managed within a component and triggers re-rendering when updated.
    • Lifecycle Methods: Lifecycle methods are functions that are called at different stages of a component's lifecycle, such as mounting, updating, and unmounting. They enable performing actions at specific points.

State and Lifecycle:

State:

Here's an example of a Counter component that uses state to manage a simple counter that increments when a button is clicked.

import React, { Component } from 'react';

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

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

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.incrementCount}>Increment</button>
      </div>
    );
  }
}

export default Counter;

Lifecycle Methods:

Here's a basic example of using lifecycle methods. The LifecycleDemo component logs messages to the console at different stages of the component's lifecycle.

import React, { Component } from 'react';

class LifecycleDemo extends Component {
  constructor(props) {
    super(props);
    console.log('Constructor');
  }

  componentDidMount() {
    console.log('Component Did Mount');
  }

  componentDidUpdate() {
    console.log('Component Did Update');
  }

  componentWillUnmount() {
    console.log('Component Will Unmount');
  }

  render() {
    return <p>Check the console for lifecycle messages</p>;
  }
}

export default LifecycleDemo;

Please note that React has introduced functional components and hooks which are more commonly used for state and lifecycle management in modern React applications. The examples provided here use class components and lifecycle methods for demonstration purposes.

  1. Event Handling:
    • Synthetic Events: React provides a cross-browser compatible event system with synthetic events. They have similar interfaces to native events and are normalized to work consistently across different browsers.

In React, a synthetic event is a cross-browser compatible wrapper around the native browser events. It is designed to provide a consistent and normalized way to handle events across different browsers. React's synthetic events mimic the behavior of native events, but they are optimized for performance and work identically across various browsers.

When you use React's event handling system, you're actually working with synthetic events.

  • Event Handling: React allows you to handle events using event handlers, which are functions that get executed when events occur, such as button clicks or form submissions.
import React from 'react';

const handleButtonClick = (event) => {
  console.log('Button clicked');
};

const EventHandlingExample = () => {
  return (
    <button onClick={handleButtonClick}>Click me</button>
  );
};

export default EventHandlingExample;
  1. Conditional Rendering:
    • If Statements and Ternary Operators: You can use if statements or ternary operators within JSX to conditionally render components or elements based on certain conditions.
import React from 'react';

const ConditionalRenderingExample = ({ isLoggedIn }) => {
  if (isLoggedIn) {
    return <p>Welcome, user!</p>;
  } else {
    return <p>Please log in.</p>;
  }
};

export default ConditionalRenderingExample;
  • Logical && Operator: The logical && operator can be used for conditional rendering by evaluating a condition and rendering a component or element only if the condition is true.
import React from 'react';

const ConditionalRenderingExample = ({ isLoggedIn }) => {
  return (
    <div>
      {isLoggedIn ? <p>Welcome, user!</p> : <p>Please log in.</p>}
    </div>
  );
};

export default ConditionalRenderingExample;

import React from 'react';

const LogicalOperatorExample = ({ showContent }) => {
  return (
    <div>
      {showContent && <p>Content is visible.</p>}
    </div>
  );
};

export default LogicalOperatorExample;
  1. Lists and Keys:
    • Lists with .map(): You can use the .map() function to iterate over an array and render a list of components or elements dynamically.
    • Keys: Keys are unique identifiers assigned to each item in a list. They help React identify and update elements efficiently when the list changes.
import React from 'react';

const ListExample = ({ items }) => {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
};

export default ListExample;
  1. Forms and Controlled Components:
    • Controlled Components: Controlled components keep the form state in the component's state. They enable two-way data binding, allowing React to manage form input values and handle form submissions efficiently.

Forms and Controlled Components: Controlled Components:

import React, { useState } from 'react';

const ControlledForm = () => {
  const [inputValue, setInputValue] = useState('');

  const handleInputChange = (event) => {
    setInputValue(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('Submitted:', inputValue);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      <button type="submit">Submit</button>
    </form>
  );
};

export default ControlledForm;
  1. React Router:
    • Routing and Navigation: React Router enables declarative routing and navigation in React applications. It allows for defining routes and rendering different components based on the URL.
    • Route Parameters: React Router supports dynamic routing with route parameters, enabling the passing of dynamic data through the URL.

React Router: Routing and Navigation:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

const Home = () => <div>Home Page</div>;
const About = () => <div>About Page</div>;

const RouterExample = () => {
  return (
    <Router>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
        </ul>
      </nav>

      <Route path="/" exact component={Home} />
      <Route path="/about" component={About} />
    </Router>
  );
};

export default RouterExample;

Route Parameters:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

const UserProfile = ({ match }) => {
  const username = match.params.username;
  return <div>User Profile: {username}</div>;
};

const RouterParamsExample = () => {
  return (
    <Router>
      <ul>
        <li><Link to="/user/john">John</Link></li>
        <li><Link to="/user/susan">Susan</Link></li>
      </ul>

      <Route path="/user/:username" component={UserProfile} />
    </Router>
  );
};

export default RouterParamsExample;
  1. Context:
    • Context Provider and Consumer: React Context allows for sharing data between components without explicitly passing it through props. It involves a Provider component to provide the data and a Consumer component to access it within child components.

Context Provider and Consumer:

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

const UserContext = createContext();

const App = () => {
  return (
    <UserContext.Provider value="John">
      <Welcome />
    </UserContext.Provider>
  );
};

const Welcome = () => {
  const username = useContext(UserContext);
  return <p>Welcome, {username}!</p>;
};

export default App;
  1. Hooks:
    • State Hook: The useState hook allows functional components to have state by providing a state value and a function to update that value.
import React, { useState } from 'react';

const StateHookExample = () => {
  const [count, setCount] = useState(0);

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

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

export default StateHookExample;
- Effect Hook: The `useEffect` hook enables performing side effects in functional components, such as fetching data or subscribing to events.
import React, { useState, useEffect } from 'react';

const EffectHookExample = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
};

export default EffectHookExample;
- Custom Hooks: Custom hooks are reusable functions that encapsulate logic and state, allowing components to share common functionality.
import React, { useState } from 'react';

const useCounter = (initialValue, step) => {
  const [count, setCount] = useState(initialValue);

  const increment = () => {
    setCount(count + step);
  };

  return { count, increment };
};

const CustomHookExample = () => {
  const counter1 = useCounter(0, 1);
  const counter10 = useCounter(0, 10);

  return (
    <div>
      <p>Counter 1: {counter1.count}</p>
      <button onClick={counter1.increment}>Increment by 1</button>

      <p>Counter 10: {counter10.count}</p>
      <button onClick={counter10.increment}>Increment by 10</button>
    </div>
  );
};

export default CustomHookExample;
  1. Redux:
    • Store, Actions, and Reducers: Redux provides a predictable state management system. It involves defining a central store, actions that describe state changes, and reducers that handle those actions to update the store.
    • Connect and mapStateToProps: The connect function in the react-redux library connects Redux store state and actions to React components. The mapStateToProps function maps the store state to component props.
// actions.js
export const increment = () => {
  return {
    type: 'INCREMENT',
  };
};

// reducers.js
const initialState = {
  count: 0,
};

const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        count: state.count + 1,
      };
    default:
      return state;
  }
};

export default counterReducer;

// App.js
import React from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import counterReducer from './reducers';
import Counter from './Counter';

const store = createStore(counterReducer);

const App = () => {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
};

export default App;
  1. Axios:
    • HTTP Requests: Axios is a widely-used library for making HTTP requests from React applications. It provides a simple and efficient way to interact with APIs, handle request and response interceptors, and handle error scenarios.

Sure, here's an example demonstrating how to use Axios to make an HTTP GET request in a React application:

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

const AxiosExample = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts')
      .then(response => {
        setData(response.data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, []);

  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {data.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
};

export default AxiosExample;

In this example, we're fetching a list of posts from the JSONPlaceholder API using Axios. The useEffect hook is used to initiate the request when the component mounts. The retrieved data is stored in the data state, and we map over it to display the post titles.

Remember to install the Axios package in your project using npm install axios. Additionally, you can configure Axios globally for your application, set up request interceptors, handle response interceptors, and handle errors according to your specific requirements.

  1. Portal:
    • React Portal is a feature in React that allows you to render children components into a different DOM node outside the parent component's hierarchy. It enables you to render content outside the normal DOM hierarchy, which can be useful for creating overlays, modals, tooltips, and other components that need to be rendered outside their parent containers.
// App.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const PortalExample = () => {
  const [showPortal, setShowPortal] = useState(false);

  const togglePortal = () => {
    setShowPortal(prevState => !prevState);
  };

  return (
    <div>
      <h1>React Portal Example</h1>
      <button onClick={togglePortal}>
        {showPortal ? 'Hide Portal Content' : 'Show Portal Content'}
      </button>

      {showPortal && ReactDOM.createPortal(
        <div className="portal-content">
          This content is rendered using React Portal and is outside the main DOM hierarchy.
        </div>,
        document.getElementById('portal-root') // Specify the portal's target DOM node
      )}
    </div>
  );
};

export default PortalExample;

In this example, we have a simple React component called PortalExample. It renders a button that toggles the visibility of the portal content. When the button is clicked, we use ReactDOM.createPortal to render the content inside the specified #portal-root div, which is located outside the main React app's DOM hierarchy.

Here's the index.html file:

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>React Portal Example</title>
  </head>
  <body>
    <div id="root"></div>
    <div id="portal-root"></div> <!-- This is where the portal content will be rendered -->
  </body>
</html>
  1. Higher Order Component

A Higher-Order Component (HOC) is a design pattern in React that allows you to reuse component logic and share functionality across different components. It is a function that takes a component as an argument and returns a new component with additional props or behavior. HOCs are useful for cross-cutting concerns such as data fetching, authentication, and other common functionalities.

Sure! Here's an easy example of a Higher-Order Component (HOC):

import React from 'react';

// Higher-Order Component
const withBackgroundColor = (WrappedComponent, color) => {
  const WithBackgroundColor = (props) => {
    return <div style={{ backgroundColor: color }}>
      <WrappedComponent {...props} />
    </div>;
  };

  return WithBackgroundColor;
};

// Component to be wrapped
const DisplayMessage = ({ message }) => {
  return <h2>{message}</h2>;
};

// Wrap DisplayMessage with the withBackgroundColor HOC
const MessageWithBackground = withBackgroundColor(DisplayMessage, 'lightblue');

// App component
const App = () => {
  return (
    <div>
      <h1>Higher-Order Component Easy Example</h1>
      <MessageWithBackground message="Hello, I have a light blue background!" />
    </div>
  );
};

export default App;

This easy example showcases how you can use Higher-Order Components to add additional functionality or styling to a component by wrapping it with a new component that adds the desired behavior.

This example is straightforward and demonstrates the concept of using React Portal to render content outside the main React app's DOM tree. When you click the "Show Portal Content" button, the content will appear outside the main #root div but within the #portal-root div. When you click "Hide Portal Content," it will disappear from the main UI. This showcases how React Portal can be used to render content outside the typical component hierarchy, making it useful for creating overlays, tooltips, modals, and more.

Understanding these concepts in-depth will empower you to build complex and robust React applications. It's essential to continuously explore the React documentation, stay up-to-date with the latest features and best practices, and practice applying these concepts in real-world projects.

⚠️ **GitHub.com Fallback** ⚠️