Mastering React Advanced Hooks with TypeScript: Simulating a Dynamic Equation System
In today’s React applications, advanced hooks like useContext
, useReducer
, and useLayoutEffect
provide powerful tools to manage state, coordinate rendering, and share data efficiently—without introducing excessive boilerplate.
In this article, we’ll implement these hooks in a real-world mathematical scenario: simulating a system of equations with shared coefficients and synchronized updates using React + TypeScript
.
Objective: Simulate and Manage Dynamic Equations
We’ll create a dynamic environment with:
- Global equation context using
useContext
- State transitions and actions using
useReducer
- Layout synchronization using
useLayoutEffect
to ensure DOM alignment before render
Hook Overview in this Context
Hook | Purpose |
---|---|
useContext |
Share coefficients across components |
useReducer |
Manage complex state transitions like equation switching |
useLayoutEffect |
Ensure the canvas and equation list align correctly before paint |
Step 1: Define Global Math Context
// MathContext.tsx
import React, { createContext, useReducer, useContext } from "react";
type Equation = {
id: string;
formula: string;
coefficients: number[];
};
type State = {
activeEquation: Equation;
};
type Action =
| { type: "SET_EQUATION"; payload: Equation };
const initialState: State = {
activeEquation: {
id: "eq1",
formula: "y = ax² + bx + c",
coefficients: [1, 2, 1]
}
};
const MathContext = createContext<{ state: State; dispatch: React.Dispatch<Action> } | undefined>(undefined);
function mathReducer(state: State, action: Action): State {
switch (action.type) {
case "SET_EQUATION":
return { ...state, activeEquation: action.payload };
default:
return state;
}
}
export const MathProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(mathReducer, initialState);
return (
<MathContext.Provider value={{ state, dispatch }}>
{children}
</MathContext.Provider>
);
};
export const useMath = () => {
const context = useContext(MathContext);
if (!context) throw new Error("useMath must be used within MathProvider");
return context;
};
Step 2: Visualizing the Equation
import { useLayoutEffect, useRef } from "react";
import { useMath } from "./MathContext";
export const EquationVisualizer = () => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const { state } = useMath();
const [a, b, c] = state.activeEquation.coefficients;
useLayoutEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas?.getContext("2d");
if (!canvas || !ctx) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
for (let x = -100; x <= 100; x++) {
const px = canvas.width / 2 + x;
const y = a * x * x + b * x + c;
const py = canvas.height / 2 - y;
x === -100 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
}
ctx.strokeStyle = "teal";
ctx.lineWidth = 2;
ctx.stroke();
}, [a, b, c]);
return <canvas ref={canvasRef} width={400} height={400} style={{ border: "1px solid gray" }} />;
};
Step 3: Dynamic Equation Switching
const EquationSelector = () => {
const { dispatch } = useMath();
const handleChange = () => {
dispatch({
type: "SET_EQUATION",
payload: {
id: "eq2",
formula: "y = 2x² - 3x + 5",
coefficients: [2, -3, 5]
}
});
};
return <button onClick={handleChange}>Switch Equation</button>;
};
App Component
import { MathProvider } from "./MathContext";
import { EquationVisualizer } from "./EquationVisualizer";
import { EquationSelector } from "./EquationSelector";
export const App = () => (
<MathProvider>
<h1>🧠 Equation Simulation</h1>
<EquationSelector />
<EquationVisualizer />
</MathProvider>
);
Key Concepts Illustrated
Hook | Role in Simulation |
---|---|
useReducer |
Equation state machine |
useContext |
Shared equation access across components |
useLayoutEffect |
Canvas DOM render before paint |
canvas + TS |
Visualize mathematical curves |
TypeScript |
Precise modeling of equations |
Conclusion
React’s advanced hooks offer the flexibility and structure needed to simulate real-world systems, including mathematical and scientific processes.
By combining useContext
, useReducer
, and useLayoutEffect
, we:
- Centralized state using reducers
- Propagated updates globally with context
- Ensured DOM synchronization before drawing equations
React isn’t just for UIs—it’s a powerful platform for modeling logic-heavy systems.
Next: Learn how to build a matrix visualizer using useMemo
+ useCallback
+ SVG
.
Tags: react
typescript
useReducer
useContext
useLayoutEffect
math
canvas
simulation
frontend
Top comments (0)