Skip to main content

Command Palette

Search for a command to run...

Day 24 of Documenting until I get a job🚀

Published
•3 min read
Day 24 of Documenting until I get a job🚀
V

Making of a developer in progress.

Jobs applied to

  • Juspay: Backend Engineer

  • Big Oh: SDE Trainee

  • Omnify: Fullstack Intern


React JS

(Yes, these notes seem AI generated) because I used personal codes and raw notes and refined them using AI

Custom hooks in react | currency Project

Custom Hooks

  • Purpose:

    • Encapsulate and reuse logic across components.

    • Simplify state management and side effects.

  • Usage Examples:

    • Handling API requests within a custom hook.

    • Managing form data or other stateful logic modularly.

API Calls & Optimization

  • API Integration:

    • Fetching currency conversion rates using a custom hook.

    • Handling asynchronous operations efficiently with useEffect.

  • Optimization Techniques:

    • Use useCallback to prevent unnecessary re-renders.

    • Optimize API calls by updating state only when necessary.

Reusable Component Design

  • Component Structure:

    • Separate logic (via custom hooks) from UI for maintainability.

    • Use reusable components for input fields and UI elements.

  • Best Practices:

    • Keep components lean by offloading logic into hooks.

    • Maintain clear and consistent data flow.

Best Practices & Debugging Tips

  • Keys in Lists: Always include unique key props when rendering lists.

  • Visual Feedback: Display code alongside its output for better understanding.

  • Incremental Learning: Break down topics into smaller parts; revisit them as needed.

  • Debugging: Check state updates and follow step-by-step debugging.


Project Code Structure

App.jsx

import { useState } from 'react';
import { InputBox } from './components';
import useCurrencyInfo from './hooks/useCurrencyInfo';

function App() {
  const [amount, setAmount] = useState(0);
  const [from, setFrom] = useState('usd');
  const [to, setTo] = useState('inr');
  const [convertedAmount, setConvertedAmount] = useState(0);

  const currencyInfo = useCurrencyInfo(from);
  const options = Object.keys(currencyInfo);

  const swap = () => {
    setFrom(to);
    setTo(from);
    setConvertedAmount(amount);
    setAmount(convertedAmount);
  };

  const convert = () => {
    setConvertedAmount(amount * currencyInfo[to]);
  };

  return (
    <div className="w-full h-screen flex justify-center items-center bg-cover bg-no-repeat"
      style={{ backgroundImage: `url('https://images.pexels.com/photos/534216/pexels-photo-534216.jpeg')` }}>
      <div className="w-full max-w-md mx-auto border border-gray-60 rounded-lg p-5 backdrop-blur-sm bg-white/30">
        <form onSubmit={(e) => { e.preventDefault(); convert(); }}>
          <InputBox label="From" amount={amount} currencyOptions={options} onCurrencyChange={setFrom} selectCurrency={from} onAmountChange={setAmount} />
          <button type="button" className="bg-blue-600 text-white px-2 py-1 rounded" onClick={swap}>Swap</button>
          <InputBox label="To" amount={convertedAmount} currencyOptions={options} onCurrencyChange={setTo} selectCurrency={to} amountDisable />
          <button type="submit" className="w-full bg-blue-600 text-white px-4 py-3 rounded-lg">Convert {from.toUpperCase()} to {to.toUpperCase()}</button>
        </form>
      </div>
    </div>
  );
}
export default App;

InputBox.jsx (Reusable Component)

import React, { useId } from 'react';

function InputBox({ label, amount, onAmountChange, onCurrencyChange, currencyOptions = [], selectCurrency = 'usd', amountDisable = false, currencyDisable = false }) {
  const amountInputId = useId();

  return (
    <div className="bg-white p-3 rounded-lg flex">
      <div className="w-1/2">
        <label htmlFor={amountInputId} className="text-black/40 mb-2 inline-block">{label}</label>
        <input id={amountInputId} className="outline-none w-full bg-transparent py-1.5" type="number" placeholder="Amount" disabled={amountDisable} value={amount} onChange={(e) => onAmountChange && onAmountChange(Number(e.target.value))} />
      </div>
      <div className="w-1/2 flex justify-end">
        <p className="text-black/40 mb-2 w-full">Currency Type</p>
        <select className="rounded-lg px-1 py-1 bg-gray-100 cursor-pointer outline-none" value={selectCurrency} onChange={(e) => onCurrencyChange && onCurrencyChange(e.target.value)} disabled={currencyDisable}>
          {currencyOptions.map((currency) => (
            <option key={currency} value={currency}>{currency}</option>
          ))}
        </select>
      </div>
    </div>
  );
}
export default InputBox;

useCurrencyInfo.js (Custom Hook for API Calls)

import { useEffect, useState } from 'react';

function useCurrencyInfo(currency) {
  const [data, setData] = useState({});

  useEffect(() => {
    fetch(`https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/${currency}.json`)
      .then((res) => res.json())
      .then((res) => setData(res[currency]));
  }, [currency]);

  return data;
}
export default useCurrencyInfo;

Key Concepts & Explanations

useId Hook

  • Generates a unique ID for elements.

  • Useful for linking label and input elements in forms.

Accessibility Attributes in HTML

  • aria-label, aria-hidden, role, etc., help improve accessibility for screen readers and assistive devices.

Why Use a Custom Hook for API Calls?

  • Separates API logic from components, improving readability.

  • Reusable across multiple components.

  • Reduces redundant API calls and optimizes performance.


Final Thoughts

  • Separation of Concerns: Keep logic (API, state) separate from UI.

  • Code Reusability: Custom hooks and reusable components help maintain clean code.

  • Optimization: Use useEffect dependencies wisely to avoid unnecessary re-fetching.