React Constructs

From NoskeWiki
Jump to navigation Jump to search

About

NOTE: This page is a daughter page of: React


Here are some React constructs that are useful to memorize, with examples in TypeScript (instead of JavaScript).

React Constructs

Components

React components are the building blocks of any React application. There are two main types: functional components (preferred) and class components.

// Functional Component with Props
import React from "react";

interface GreetingProps {
  name: string;
}

const Greeting: React.FC<GreetingProps> = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};

export default Greeting;

Hooks are commonly used with functional components to manage state and side effects:

// State and Effect Hook
import React, { useState, useEffect } from "react";

const Counter: React.FC = () => {
  const [count, setCount] = useState<number>(0);

  useEffect(() => {
    console.log(`Count updated: ${count}`);
  }, [count]); // Dependency array

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

export default Counter;

Class Components (less common now but still supported):

import React, { Component } from "react";

interface State {
  count: number;
}

class Counter extends Component<{}, State> {
  state: State = { count: 0 };

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

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

export default Counter;

---

Fetching Data from a Backend

React commonly interacts with backends using `fetch` or libraries like Axios.

Using Fetch with Promises:

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

interface User {
  id: number;
  name: string;
  email: string;
}

const Users: React.FC = () => {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch("https://jsonplaceholder.typicode.com/users");
      const data: User[] = await response.json();
      setUsers(data);
    };

    fetchUsers();
  }, []); // Empty dependency array: run only on mount

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name} ({user.email})</li>
      ))}
    </ul>
  );
};

export default Users;

Using Axios:

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

interface Post {
  id: number;
  title: string;
  body: string;
}

const Posts: React.FC = () => {
  const [posts, setPosts] = useState<Post[]>([]);

  useEffect(() => {
    axios.get<Post[]>("https://jsonplaceholder.typicode.com/posts")
      .then(response => setPosts(response.data))
      .catch(error => console.error(error));
  }, []);

  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </div>
      ))}
    </div>
  );
};

export default Posts;

---

Handling Promises

React components often deal with asynchronous data. Use async/await for clarity:

const fetchData = async (): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Data loaded!"), 2000);
  });
};

const App: React.FC = () => {
  const [message, setMessage] = useState<string>("Loading...");

  useEffect(() => {
    const load = async () => {
      const data = await fetchData();
      setMessage(data);
    };

    load();
  }, []);

  return <p>{message}</p>;
};

export default App;

---

Forms and Controlled Components

React uses controlled components to handle form input:

import React, { useState } from "react";

const Form: React.FC = () => {
  const [name, setName] = useState<string>("");

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    alert(`Submitted name: ${name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button type="submit">Submit</button>
    </form>
  );
};

export default Form;

---

Routing with React Router

React Router is a popular library for navigation:

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

const Home: React.FC = () => <h1>Home</h1>;
const About: React.FC = () => <h1>About</h1>;

const App: React.FC = () => {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
};

export default App;

---

Context API

React Context is used for managing global state:

import React, { createContext, useContext, useState } from "react";

const ThemeContext = createContext<string>("light");

const ThemeProvider: React.FC = ({ children }) => {
  const [theme, setTheme] = useState("light");

  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
};

const ThemedComponent: React.FC = () => {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
};

const App: React.FC = () => (
  <ThemeProvider>
    <ThemedComponent />
  </ThemeProvider>
);

export default App;

---

See Also