ReactJS Conditional Rendering: UI වෙනස් කරන හැටි | Sinhala Guide

ReactJS Conditional Rendering: UI වෙනස් කරන හැටි | Sinhala Guide

ආයුබෝවන් යාළුවෝ! 🙋‍♂️

අද අපි කතා කරන්න යන්නේ ReactJS වල ගොඩක් වැදගත් concept එකක් ගැන. ඒ තමයි Conditional Rendering. වෙබ් ඇප්ලිකේෂන් එකක් හදනකොට අපිට ගොඩක් වෙලාවට සිද්ධ වෙනවා යම්කිසි තත්වයක් (condition) මත UI එකේ කොටස් වෙනස් කරන්න. උදාහරණයක් විදිහට, user කෙනෙක් log වෙලාද නැද්ද කියන එක අනුව වෙනස් දේවල් පෙන්නන්න, නැත්නම් දත්ත load වෙනකල් loading spinner එකක් පෙන්නලා, load වුණාට පස්සේ දත්ත ටික පෙන්නන්න වගේ දේවල්.

මේ Conditional Rendering කියන එක තමයි අපිට මේ වගේ දේවල් පහසුවෙන් කරන්න උදව් කරන්නේ. මේ ලිපියෙන් අපි බලමු Conditional Rendering කියන්නේ මොකක්ද, ඒක කරන්න පුළුවන් ක්‍රම මොනවද, practical උදාහරණ කිහිපයක් සහ මේක පාවිච්චි කරනකොට මතක තියාගන්න ඕන වැදගත් කරුණු මොනවද කියලා. එහෙනම් වැඩේට බහිමුද? 😎

Conditional Rendering කියන්නේ මොකක්ද?

සරලවම කිව්වොත්, Conditional Rendering කියන්නේ ReactJS component එකක, යම්කිසි condition එකක් මත පදනම් වෙලා, වෙනස් UI elements හෝ components display කරන එකට. හිතන්න ඔයාගේ ගෙදර light switch එකක් වගේ. ඒක on කරනකොට එළිය එනවා, off කරනකොට අඳුරු වෙනවා. මෙතන condition එක තමයි switch එකේ state එක. ඒ වගේම, ReactJS වලදීත් අපිට පුළුවන් state, props, හෝ වෙනත් ඕනෑම JavaScript variable එකක වටිනාකමක් මත පදනම් වෙලා, අපේ UI එක වෙනස් කරන්න.

මේක ඇයි වැදගත්? මොකද අපේ web applications හැමවෙලේම එක විදිහට නෑනේ. User interactions, API responses, user permissions වගේ දේවල් අනුව UI එක dynamically වෙනස් වෙන්න ඕන. Conditional Rendering මේකට තමයි ප්‍රධාන විසඳුම දෙන්නේ.

Conditional Rendering ක්‍රම

ReactJS වල Conditional Rendering කරන්න අපිට ප්‍රධාන ක්‍රම කිහිපයක් තියෙනවා. අපි එකින් එක බලමු.

1. `if/else` Statement එක

මේක තමයි JavaScript වල තියෙන සරලම conditional statement එක. ReactJS component එකක return statement එකට පිටතින් මේක පාවිච්චි කරන්න පුළුවන්. return එක ඇතුලේ (JSX) අපිට if/else කෙලින්ම පාවිච්චි කරන්න බෑ.

උදාහරණයක් බලමු:

function Greeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <h1>ආයුබෝවන්, නැවත සාදරයෙන් පිළිගනිමු!</h1>; // Welcome back!
  } else {
    return <h1>කරුණාකර log වෙන්න.</h1>; // Please log in.
  }
}

// මේක පාවිච්චි කරන විදිහ:
// <Greeting isLoggedIn={true} />  // output: "ආයුබෝවන්, නැවත සාදරයෙන් පිළිගනිමු!"
// <Greeting isLoggedIn={false} /> // output: "කරුණාකර log වෙන්න."

මේ ක්‍රමය හොඳයි complex conditions තියෙනකොට, නැත්නම් component එක සම්පූර්ණයෙන්ම වෙනස් දෙයක් render කරන්න ඕන නම්. නමුත්, එකම component එක ඇතුලේ පොඩි පොඩි වෙනස්කම් කරන්න මේක ටිකක් අපහසු වෙන්න පුළුවන්.

2. Ternary Operator (`? :`)

මේක JavaScript වල තියෙන තවත් ඉතාම ප්‍රයෝජනවත් operator එකක්. මේක අපිට JSX ඇතුලෙම conditional rendering කරන්න පුළුවන් නිසා ගොඩක් ජනප්‍රියයි. මේකේ syntax එක මේ වගේ:

condition ? expressionIfTrue : expressionIfFalse

condition එක true නම් expressionIfTrue execute වෙනවා, නැත්නම් expressionIfFalse execute වෙනවා.

උදාහරණයක් බලමු, කලින් Greeting component එකම Ternary Operator එකෙන් හදන හැටි:

function GreetingTernary({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? (
        <h1>ආයුබෝවන්, නැවත සාදරයෙන් පිළිගනිමු!</h1>
      ) : (
        <h1>කරුණාකර log වෙන්න.</h1>
      )}
    </div>
  );
}

// මේක පාවිච්චි කරන විදිහ:
// <GreetingTernary isLoggedIn={true} />

if/else වලට වඩා මේක JSX ඇතුලේ පාවිච්චි කරන්න පුළුවන් නිසා, short conditions වලට මේක ගොඩක් පහසුයි.

3. Logical AND Operator (`&&`)

මේක තවත් ගොඩක් වෙලාවට පාවිච්චි වෙන ක්‍රමයක්, විශේෂයෙන්ම අපිට යම්කිසි component එකක් render කරන්න ඕන condition එක true නම් විතරක්, false වුණොත් මොකුත් render කරන්න ඕන නැත්නම්.

JavaScript වල && operator එකේ හැසිරීම තමයි: expression1 && expression2. මෙහිදී, expression1 එක true නම්, expression2 එක evaluate කරලා ඒකේ වටිනාකම return කරනවා. expression1 එක false නම්, expression1 එකේ වටිනාකමම return කරනවා.

ReactJS වලදී, JSX එකක් true value එකක් වගේ consider වෙනවා. ඉතින්, condition && <Component /> කියලා ලිව්වොත්, condition එක true නම් <Component /> එක render වෙනවා. condition එක false නම්, false value එක return වෙනවා, ඒක ReactJS ignore කරන නිසා මොකුත් render වෙන්නේ නෑ.

උදාහරණයක්:

function Warning({ hasError }) {
  return (
    <div>
      {hasError && <p style={{ color: 'red' }}>අනතුරු ඇඟවීම: දත්ත loading කිරීමේ දෝෂයක්!</p>}
      <p>අපි සාමාන්‍යයෙන් පෙන්නන දේවල්.</p>
    </div>
  );
}

// මේක පාවිච්චි කරන විදිහ:
// <Warning hasError={true} />  // output: අනතුරු ඇඟවීම: දත්ත loading කිරීමේ දෝෂයක්!
//                               //         අපි සාමාන්‍යයෙන් පෙන්නන දේවල්.
// <Warning hasError={false} /> // output: අපි සාමාන්‍යයෙන් පෙන්නන දේවල්.

මේක ගොඩක් පහසුයි, හැබැයි පොඩි ප්‍රශ්නයක් තියෙනවා! අපි වැදගත් කරුණු කොටසේදී ඒ ගැන කතා කරමු.

4. Elements as Variables

සමහර වෙලාවට අපිට rendering කරන්න ඕන දේ complex වෙන්න පුළුවන්. එතකොට අපිට පුළුවන් JSX element එකක් variable එකකට assign කරලා, ඒ variable එක return statement එක ඇතුලේ render කරන්න.

function AdminPanel({ userRole }) {
  let content;

  if (userRole === 'admin') {
    content = <h3>Admin Dashboard එකට සාදරයෙන් පිළිගනිමු!</h3>;
  } else if (userRole === 'moderator') {
    content = <h3>Moderator Tools මෙහි ඇත.</h3>;
  } else {
    content = <h3>ඔබට මෙම පිටුවට ප්‍රවේශ වීමට අවසර නැත.</h3>;
  }

  return (
    <div>
      <h2>පරිපාලන පැනලය</h2>
      {content}
    </div>
  );
}

// <AdminPanel userRole="admin" />

මේ ක්‍රමය, logic එක return statement එකෙන් වෙන් කරලා තියන්න උදව් කරනවා, ඒ නිසා code එක කියවන්න පහසු වෙනවා.

ප්‍රායෝගික උදාහරණ

දැන් අපි මේ Conditional Rendering concept එක practical විදිහට පාවිච්චි කරන හැටි බලමු.

1. Login/Logout බොත්තම සහ Welcome පණිවිඩය

අපි හදමු login/logout state එක manage කරන component එකක්. User කෙනෙක් log වෙලාද නැද්ද කියලා බලලා, ඊට අදාළව message එකක් සහ බොත්තමක් පෙන්නමු.

import React, { useState } from 'react';

function UserPanel() {
  const [isLoggedIn, setIsLoggedIn] = useState(false); // Default state: Not logged in

  const handleLogin = () => {
    setIsLoggedIn(true);
    console.log("User logged in!");
  };

  const handleLogout = () => {
    setIsLoggedIn(false);
    console.log("User logged out!");
  };

  return (
    <div style={{ border: '1px solid #ccc', padding: '20px', margin: '20px' }}>
      <h3>පරිශීලක පැනලය</h3>
      {isLoggedIn ? (
        <>
          <p><strong>ආයුබෝවන්, පරිශීලකයා!</strong> ඔබ සාදරයෙන් පිළිගනිමු.</p>
          <button onClick={handleLogout}>Logout</button>
        </>
      ) : (
        <>
          <p>ඔබ log වෙලා නෑ. කරුණාකර log වෙන්න.</p>
          <button onClick={handleLogin}>Login</button>
        </>
      )}
    </div>
  );
}

// මේක ඔයාගේ App.js එකේ පාවිච්චි කරන්න පුළුවන්:
// function App() {
//   return (
//     <div>
//       <UserPanel />
//     </div>
//   );
// }

මෙතනදී අපි useState Hook එක පාවිච්චි කරලා isLoggedIn කියන state එක හදාගෙන තියෙනවා. ඒ state එකේ අගය අනුව Ternary Operator එකෙන් UI එක වෙනස් කරලා තියෙනවා. ඒ වගේම, Fragment (<></>) එකක් පාවිච්චි කරලා තියෙන්නේ, Ternary Operator එක ඇතුලේ elements කිහිපයක් return කරනකොට ඒ හැම එකක්ම single parent element එකකින් wrap කරන්න ඕන නිසා.

2. Data Loading Spinner එක

API call එකක් කරලා data fetch කරනකොට, data load වෙනකල් loading spinner එකක් පෙන්නන එක ගොඩක් සාමාන්‍ය දෙයක්. Data load වුණාට පස්සේ spinner එක අයින් කරලා data ටික පෙන්නන හැටි බලමු.

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

function DataLoader() {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // මේක API call එකක් simulate කරනවා
    setTimeout(() => {
      setData({ message: 'මෙන්න ඔයාගේ දත්ත! අපි සාර්ථකව data load කළා.' });
      setIsLoading(false); // Data load වුණාට පස්සේ loading ඉවරයි කියලා කියනවා
    }, 2000); // තත්පර 2ක් loading simulate කරනවා
  }, []); // Component එක mount වෙනකොට විතරක් run වෙන්න

  return (
    <div style={{ border: '1px solid #ccc', padding: '20px', margin: '20px' }}>
      <h3>දත්ත ලබාගැනීම</h3>
      {isLoading ? (
        <p>දත්ත loading වෙමින් පවතී... <span className="spinner" role="img" aria-label="loading">⚙️</span></p>
      ) : (
        <p>{data.message}</p>
      )}
    </div>
  );
}

// <DataLoader />

මේ උදාහරණයේදී අපි useState වලින් data සහ isLoading කියන state දෙක define කරලා තියෙනවා. useEffect Hook එක ඇතුලේ අපි setTimeout එකක් පාවිච්චි කරලා asynchronous data fetching එකක් simulate කරලා තියෙනවා. isLoading state එක true වෙනකල් loading message එකයි spinner එකයි පේනවා. setTimeout එක ඉවර වුණාට පස්සේ isLoading false වෙලා, data.message එක display වෙනවා.

වැදගත් කරුණු සහ Best Practices

1. Component Re-rendering

ReactJS වල component එකක state හෝ props වෙනස් වුණොත්, ඒ component එක නැවත render වෙනවා (re-render). මේ re-rendering වෙන වෙලාවට තමයි conditional logic එක නැවත run වෙන්නේ, අලුත් condition එක අනුව අලුත් UI එකක් display වෙන්නේ. මේක ReactJS වල performance වලට බලපාන්නේ නැද්ද කියලා සමහර අයට හිතෙන්න පුළුවන්. සාමාන්‍යයෙන්, ReactJS මේ re-rendering process එක ගොඩක් efficiently manage කරනවා. අවශ්‍යම නැත්නම් DOM එකේ වෙනස්කම් කරන්නේ නෑ.

2. `&&` Operator එකේ ප්‍රශ්න

අපි කලින් කතා කරපු && operator එක ගොඩක් පහසු වුණත්, ඒකේ පොඩි trap එකක් තියෙනවා. expression1 && expression2 කියන එකේදී expression1 එක false වගේ evaluate වෙන JavaScript values (false, 0, null, undefined, NaN, "" - empty string) වුණොත්, ඒ value එක render වෙන්න පුළුවන්!

උදාහරණයක්:

// වැරදි විදිහ
function ItemCount({ count }) {
  return (
    <div>
      <p>අයිතම ගණන: {count && <span>{count}</span>}</p>
      {/* If count is 0, this will render "අයිතම ගණන: 0".
          අපිට ඕන නැත්තම් "0" පෙන්නන්න, මේක ප්‍රශ්නයක්. */}
    </div>
  );
}

// <ItemCount count={0} /> // output: "අයිතම ගණන: 0"
// <ItemCount count={5} /> // output: "අයිතම ගණන: 5"

මේකෙන් බේරෙන්න පුළුවන් ක්‍රම කිහිපයක් තියෙනවා:

  • Boolean() function එක පාවිච්චි කරන එක:
  • Ternary Operator එක පාවිච්චි කරන එක:
function ItemCountTernary({ count }) {
  return (
    <div>
      <p>අයිතම ගණන: {count ? <span>{count}</span> : 'නැත'}</p>
    </div>
  );
}
// <ItemCountTernary count={0} /> // output: "අයිතම ගණන: නැත"
function ItemCountFixed({ count }) {
  return (
    <div>
      <p>අයිතම ගණන: {Boolean(count) && <span>{count}</span>}</p>
    </div>
  );
}
// <ItemCountFixed count={0} /> // output: "අයිතම ගණන:" (0 එක render වෙන්නේ නෑ)

මේ වගේ තැන් වලදී Boolean() හෝ Ternary Operator එක පාවිච්චි කරන එක ගොඩක් ආරක්ෂාකාරීයි.

3. Conditional Logic තියන්න ඕන කොහෙද?

Simple conditions නම් return statement එක ඇතුලේ (JSX) Ternary Operator හෝ && operator එකෙන් ලියන එක හොඳයි. හැබැයි logic එක complex වෙනකොට, return එකට කලින් වෙනම variables වලට elements assign කරගන්න එක (elements as variables) හෝ වෙනම helper functions වලට logic එක වෙන් කරන එක code එක maintain කරන්න පහසු කරනවා.

උදාහරණයක්: වෙනම component එකක් හදන එක.

// Helper Component
function LogoutButton({ onClick }) {
  return <button onClick={onClick}>Logout</button>;
}

function LoginButton({ onClick }) {
  return <button onClick={onClick}>Login</button>;
}

function AuthControls({ isLoggedIn, onLogin, onLogout }) {
  if (isLoggedIn) {
    return <LogoutButton onClick={onLogout} />;
  }
  return <LoginButton onClick={onLogin} />;
}

// Main component එක ඇතුලේ මෙහෙම පාවිච්චි කරන්න පුළුවන්:
// <AuthControls isLoggedIn={isLoggedIn} onLogin={handleLogin} onLogout={handleLogout} />

මේකෙන් component එකේ readability එක වැඩි වෙනවා.

නිගමනය (Conclusion)

ඔන්න ඉතින් යාළුවනේ, අපි ReactJS වල Conditional Rendering කියන දේ ගැන ගොඩක් දේවල් කතා කළා. මේ concept එක ReactJS වලින් dynamic, responsive සහ user-friendly applications හදන්න අතිශයින්ම වැදගත්.

අපි ඉගෙනගත්තා if/else statements, Ternary Operator (`? :`), Logical AND Operator (`&&`) සහ Elements as Variables කියන ක්‍රම පාවිච්චි කරලා කොහොමද UI එකේ කොටස් condition එකක් මත වෙනස් කරන්නේ කියලා. ඒ වගේම, මේක පාවිච්චි කරනකොට මතක තියාගන්න ඕන Pitfalls (විශේෂයෙන් && operator එකේ) සහ Best Practices ගැනත් කතා කළා.

දැන් ඔයාට මේ සංකල්පය අරගෙන ඔයාගේම ReactJS project වලට යොදවන්න පුළුවන්! 🚀 මේක practice කරනකොට තමයි ගොඩක් දේවල් පැහැදිලි වෙන්නේ. පහළින් comment එකක් දාලා ඔයාගේ අදහස් share කරන්න අමතක කරන්න එපා! මේ ලිපිය ඔයාට ප්‍රයෝජනවත් වුණා නම්, අනිත් යාළුවොත් එක්කත් share කරන්න. ජය වේවා! ✨