React: Sockets, Composition, Events and Routing
Notes from the summary of COMP3011 Lecture 8, 9, 10, and online resources.
Real-Time Communication and React Fundamentals
Pub/Sub Architecture
The Publish-Subscribe (Pub/Sub) messaging pattern:
- Publishers send messages to a “topic” without needing to know who will receive them.
- Subscribers listen for messages on specific topics they are interested in.
This model is commonly used in real-time applications where decoupling of message producers and consumers is important.
Socket.io and Real-Time Communication
Socket.io enables real-time, bidirectional communication between a server and client using WebSockets, with automatic fallbacks for HTTP-based transports when needed.
Key Concepts:
- Installation:
npm install express socket.io -
Server-side setup: Uses Express.js and configures Socket.io to listen and broadcast events.
-
Client-side implementation: Includes a basic HTML form for publishing and JavaScript for subscribing to events.
- Extensions suggested:
- Authentication
- Multiple topic subscriptions
- Real-time chat application
React and Single-Page Applications (SPAs)
React, a JavaScript library for building dynamic UIs, especially SPAs.
SPA Characteristics:
- Load a single HTML page.
- Dynamically update content using AJAX, fetch, or WebSockets.
- Faster transitions and seamless user experiences.
-
URL changes handled on the client side.
- Pros:
- Smooth user experience
- Reduced server load
- Fast UI interactions
- Cons:
- Larger initial load time
- More complex client-side logic
React Core Concepts
React encourages breaking down UIs into small, reusable components:
- Functional Components: Stateless and written as plain functions.
- Class Components: Support local state and lifecycle methods.
Key Features:
- Declarative Programming: Describe what you want, not how.
- Virtual DOM: Efficient updates without redrawing the whole UI.
- JSX: Syntax extension for writing HTML-like code inside JavaScript.
- Unidirectional Data Flow: Data flows from parent to child via props.
Managing State and Props
- Props: Read-only data passed into components.
- State: Internal mutable data that triggers UI updates.
Updating State:
this.setState({ key: value });
Dynamic Rendering:
- Use
.map()for rendering lists. - Conditional rendering using ternary operators or if-else logic.
Event Handling
- Events use camelCase syntax (e.g.,
onClick). - Bind methods in the constructor for class components.
- Pass event arguments via arrow functions.
Summary
- Socket.io enables low-latency, real-time communication.
- React offers a modular, component-driven way to build SPAs.
- JSX, props, and state are foundational concepts in React.
- By separating data and presentation, React simplifies the development of dynamic, interactive UIs.
- React enables powerful in-browser logic without frequent server requests.
Component-Based Architecture
React is all about building user interfaces by breaking them down into smaller, reusable pieces called components. Each component is an independent unit responsible for rendering a specific part of the UI and managing its own data (state).
- Reusability: Components like buttons, inputs, or navigation bars can be reused throughout the app without rewriting code.
- Maintainability: Since components are self-contained, they are easier to understand, test, and update.
- Organization: Modular structure makes code easier to reason about, especially in large applications.
Relationship and Data Flow
React components are organized in a hierarchy:
- Parent to Child: Data flows from parent to child via props (properties).
- Unidirectional Data Flow: Child components receive props and invoke parent functions (passed down as props) to request data updates.
This structure enforces predictability, clear separation of concerns, and easier debugging.
Function-Based vs. Class-Based
React supports two main types of components:
Class Components
These use ES6 classes and manage state and lifecycle methods.
import React from 'react';
class MyClassComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
export default MyClassComponent;
Function Components
Simpler syntax, originally stateless, now enhanced with Hooks.
import React from 'react';
function MyFunctionComponent(props) {
return (
<div>
<p>Name: {props.name}</p>
</div>
);
}
export default MyFunctionComponent;
The Rise of Hooks
React 16.8 introduced Hooks, enabling function components to manage state and side effects.
useState: Adds state variables.useEffect: Handles side effects (e.g., API calls, subscriptions).
Hooks make function components powerful and concise. They are now the recommended way to write components.
Summary
- React structures UIs as reusable components.
- Provides class-based and hook-enabled function components.
- Component Composition: Complex UIs are built from smaller, isolated components.
- File Extensions: Use
.jsx,.tsx,.js,.tsdepending on JSX and TypeScript use. - Props: Passed from parent to child. Read-only.
- props.children: Represents nested elements passed from parent.
- Event Handling: Parent provides a callback function to respond to child-triggered events.
- State Management: Keep state high for global control, lower for performance optimization.
- Stateless Functional Components: Simple functions that return JSX.
- Static Files: Use
public/for globally accessible assets or import assets locally into components.
React Hooks and Modern State Management
- Hooks introduced in React 16.8 allow functional components to manage state and lifecycle.
- Key hooks include:
useState: Manages local state.useEffect: Handles side effects (e.g., API calls).useContext,useRef,useReducer: For context, DOM refs, and complex state logic.
Rules of Hooks:
- Only use hooks at the top level of functional components.
- Do not call hooks inside loops, conditions, or nested functions.
Linking React with a Backend (CORS)
- Enable CORS in Express to allow requests from a React frontend:
const cors = require('cors'); app.use(cors());
Routing in React with react-router-dom
- Install:
npm install react-router-dom - Components:
<BrowserRouter>: Manages history via the HTML5 API.<Routes>and<Route>: Define client-side paths.<Link>: Navigation between views without reloading.
Example Setup
Navbar with React Bootstrap:
<Nav.Link as={Link} to="/">Home</Nav.Link>
<Nav.Link as={Link} to="/cart">Cart</Nav.Link>
App Routing:
<Routes>
<Route path="/" element={<Shop />} />
<Route path="/cart" element={<CounterList />} />
<Route path="*" element={<Navigate to="/" />} />
</Routes>
Axios and HTTP Requests
- Install:
npm i axios - Example GET:
const { data: products } = await axios.get('https://jsonplaceholder.typicode.com/posts'); - Example POST:
const { data: product } = await axios.post(url, newProduct);
React Developer Tools
- Chrome/Firefox extensions for inspecting the component tree, props, and state.
- Aids in debugging and understanding application behavior.
Summary
- React Router provides client-side navigation using
<BrowserRouter>,<Routes>, and<Link>. - Axios enables RESTful communication with backend services.
- State and props control dynamic rendering and reactivity in the app.
- DevTools enhance understanding and debugging of React components.
Leave a comment