DEV Community

banti kevat
banti kevat

Posted on • Originally published at itinfohubs.blogspot.com

React Render Props Pattern Kya Hai

React Render Props Pattern Kya Hai (in Hindi)
React Render Props Pattern क्या है और इसे code reusability के लिए कैसे use करें? इस detailed Hindi guide में complete steps और examples के साथ सीखें।

दोस्तों, क्या आपके साथ कभी ऐसा हुआ है कि आप ReactJS में दो अलग-अलग components बना रहे हों, और अचानक आपको एहसास हो कि दोनों Components का state logic बिल्कुल identical (एक जैसा) है? जैसे कि एक Dynamic Dropdown और एक Modal Popup, दोनों को ही open/close होने के लिए एक ही तरह के toggle boolean state की जरूरत होती है। अब सवाल यह आता है कि क्या हम इस logic को दोबारा लिखने के बजाय कहीं reusable बना सकते हैं? यहीं पर एंट्री होती है React के एक बेहद ताकतवर design pattern की, जिसे हम React Render Props Pattern कहते हैं।

⚡ Quick Answer: React Render Props Pattern एक ऐसी technique है जिसमें हम React components के बीच state logic को share करने के लिए एक prop का use करते हैं, जिसकी value एक render function होती है। यह component खुद कुछ render करने के बजाय इस function को call करके data को UI rendering के लिए delegate कर देता है।
आज इस deep-dive tutorial में, हम और आप मिलकर इस pattern का postmortem करेंगे। एक senior developer के नजरिए से हम समझेंगे कि React Hooks के आने के बाद भी इस pattern की क्या relevance है, और इसे production-grade projects में कैसे implement किया जाता है। तो चाय का कप बगल में रख लीजिए, और चलिए शुरू करते हैं!

React Render Props Pattern क्या है? (What is Render Props Pattern?)

सरल शब्दों में कहें तो, React Render Props Pattern एक ऐसा coding design pattern है जहां एक component को एक specialized prop पास किया जाता है। इस prop की value कोई string, object या array नहीं होती, बल्कि एक JavaScript Function होती है। यह function तय करता है कि स्क्रीन पर क्या render होगा।

जब आप किसी component को render props pattern के साथ design करते हैं, तो वह component खुद अपनी कोई HTML markup (UI) render नहीं करता। इसके बजाय, वह सिर्फ अपने internal state और business logic को handle करता है, और उस state dynamic data को उसी render prop function के argument के रूप में पास कर देता है।

इस pattern की official definition को आप React Official Documentation पर भी देख सकते हैं।

ध्यान देने वाली बात ये है कि इस prop का नाम "render" होना बिल्कुल भी जरूरी नहीं है। आप इसका नाम render, children, renderUI, या जो मन करे रख सकते हैं। मुख्य बात यह है कि वह prop एक function होना चाहिए जो JSX return करे।

आखिर हमें Render Props Pattern की जरूरत क्यों पड़ी? (Why do we need it?)

React में reusable code लिखना सबसे बड़ी कला है। मान लीजिए आपके पास दो components हैं:

  • MouseTracker: जो screen पर mouse के coordinates (X, Y) track करता है और एक बिल्ली (cat) की image को उस coordinate पर दिखाता है।
  • Tooltip: जो mouse coordinates को track करके एक tooltip box की position set करता है।

यहाँ दोनों ही cases में, mouse coordinates (X, Y) को track करने का logic बिल्कुल copy-paste है। अगर हम traditional approach से जाएँगे, तो हमें दोनों components में useState और useEffect का setup बार-बार लिखना पड़ेगा।

इस logic duplication को खत्म करने के लिए हमारे पास तीन रास्ते होते हैं:

  1. Higher-Order Components (HOC)
  2. React Render Props Pattern
  3. Custom React Hooks

HOCs के साथ "wrapper hell" और naming conflicts की बड़ी समस्या होती थी, जिसके कारण Render Props Pattern काफी लोकप्रिय हुआ।

Render Props Pattern का Architecture Flow

यह pattern कैसे काम करता है, इसे समझने के लिए नीचे दिए गए component flow design को ध्यान से देखिए:

🏗️ Render Props Pattern Flow

Parent Component

Wrapper Component (Logic inside)

Render Function (State sent back)

Custom UI rendered on screen

Diagram: Wrapper component maintains state, passes state to the render prop function, which returns actual JSX back to the screen.

Step-by-Step Implementation: Live Coding Example

चलिए, अब हवा में बातें बंद करते हैं और सीधे code editor में चलते हैं। हम एक complete, production-ready live example बनाएंगे।

हम एक Mouse Tracker Component बनाएंगे जो mouse coordinates को state में hold करेगा, और किसी भी consumer component को screen पर tracking UI render करने की आज़ादी देगा।

Step 1: Wrapper Component बनाना (The Logic Provider)

सबसे पहले, हम MouseTracker.jsx component बनाएंगे जो mouse coordinates को capture करने का logic contain करेगा।

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

// यह component खुद कोई UI render नहीं करता, सिर्फ state pass करता है
const MouseTracker = ({ render }) => {
  const [coords, setCoords] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const handleMouseMove = (event) => {
      setCoords({
        x: event.clientX,
        y: event.clientY,
        windowWidth: window.innerWidth,
        windowHeight: window.innerHeight
      });
    };

    window.addEventListener('mousemove', handleMouseMove);

    // Event listener clean up करना न भूलें (Memory leak prevention)
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
    };
  }, []);

  // यहाँ हम 'render' prop को call कर रहे हैं और coordinate state parameter के रूप में भेज रहे हैं
  return (
    <div style={{ height: '100vh', width: '100%', position: 'relative' }}>
      {render(coords)}
    </div>
  );
};

export default MouseTracker;

Enter fullscreen mode Exit fullscreen mode

Step 2: Consumer Component में Logic Reuse करना

अब हमारे पास MouseTracker ready है। चलिए, अब हम दो अलग-अलग UI components में इस logic को dynamically reuse करते हैं।

import React from 'react';
import MouseTracker from './MouseTracker';

// First Consumer: सिर्फ coordinates text render करेगा
const CoordinateTextDisplay = () => {
  return (
    <div style={{ padding: '20px', background: '#f3f4f6', borderRadius: '8px' }}>
      <h3>🔴 Real-time Mouse Tracker</h3>
      <MouseTracker 
        render={({ x, y }) => (
          <p style={{ fontSize: '18px', fontWeight: 'bold' }}>
            The mouse is currently at <span style={{ color: '#ef4444' }}>X: {x}</span>, <span style={{ color: '#3b82f6' }}>Y: {y}</span>
          </p>
        )} 
      />
    </div>
  );
};

// Second Consumer: Screen पर एक सुंदर dynamic circle render करेगा जो mouse pointer को follow करेगा
const MagicPointerDisplay = () => {
  return (
    <div style={{ background: '#1e1b4b', minHeight: '400px', position: 'relative', overflow: 'hidden', color: '#ffffff' }}>
      <h3 style={{ padding: '20px' }}>✨ Move your mouse here to see magic!</h3>
      <MouseTracker 
        render={({ x, y }) => (
          <div 
            style={{
              position: 'absolute',
              top: y - 25,
              left: x - 25,
              width: '50px',
              height: '50px',
              backgroundColor: '#10b981',
              borderRadius: '50%',
              pointerEvents: 'none',
              boxShadow: '0 0 20px #10b981',
              transition: 'transform 0.05s linear'
            }}
          />
        )} 
      />
    </div>
  );
};

// Main App Component जहाँ दोनों logic reuse हो रहे हैं
const App = () => {
  return (
    <div style={{ padding: '40px', fontFamily: 'sans-serif', display: 'flex', flexDirection: 'column', gap: '30px' }}>
      <h1>React Render Props Pattern Implementation</h1>
      <CoordinateTextDisplay />
      <MagicPointerDisplay />
    </div>
  );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

देखा आपने? MouseTracker component ने coordinate tracking का भारी-भरकम logic handle कर लिया, और दोनों child elements (text display और bubble magic display) ने बिना tracking state logic लिखे सिर्फ UI render करने पर ध्यान केंद्रित किया।

Using Children as a Render Prop

कई developers को render={} prop लिखना थोड़ा अजीब या verbose लगता है। React में, आप direct custom prop के बजाय standard children prop का use करके भी Render Props Pattern implement कर सकते हैं।

आइए देखते हैं इसे कैसे लिखते हैं:

// Wrapper Component with children prop
const ScrollTracker = ({ children }) => {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      setScrollY(window.scrollY);
    };
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  // यहाँ हम custom 'render' function की जगह 'children' function call कर रहे हैं
  return children(scrollY);
};

// Parent Component usage
const ScrollApp = () => {
  return (
    <ScrollTracker>
      {(scrollY) => (
        <div style={{ position: 'fixed', top: 10, right: 10, background: 'black', color: 'white', padding: '10px' }}>
          You scrolled: {scrollY}px
        </div>
      )}
    </ScrollTracker>
  );
};

Enter fullscreen mode Exit fullscreen mode

Comparison: Render Props vs HOC vs Custom Hooks

React ecosystem में core state logical patterns के बीच की तुलना समझना बेहद जरूरी है। आइए इस comparison table से देखें कि कब कौन-सा pattern select करना चाहिए:

Pattern / Feature Render Props Higher-Order Components (HOC) Custom Hooks
Complexity Medium High (requires functional wrapping) Low (most modern)
Props Collision / Naming Conflict No (Explicitly pass parameters) Yes (Implicit props overwrite) No (Variables are returned)
Component Hierarchy Bloat Moderate High (Creates wrapper components) None (Pure JS logic injection)
Best Use Case Dynamic rendering based on runtime parent state Cross-cutting concerns (Auth wrapper, analytics logging) API fetching, pure logic separation, utility state

Performance Issues और उनका समाधान (Fixing Performance & Errors)

जब आप Render Props Pattern use करते हैं, तो अक्सर developers कुछ common errors या performance pitfalls का शिकार हो जाते हैं। आइए उनके बारे में विस्तार से समझें ताकि आपके application में कोई error या lag न आए।

1. Anonymous Functions और Re-renders की समस्या

सबसे बड़ी performance issue तब आती है जब आप inline anonymous function को render prop में direct pass करते हैं, जैसे:

<MouseTracker render={(coords) => <DisplayCoords coords={coords} />} />
Enter fullscreen mode Exit fullscreen mode

गड़बड़ क्या है?

हर बार जब container component re-render होगा, तब-तब एक नया function reference (anonymous function) memory में create होगा। अगर React virtual DOM comparison करेगा, तो उसे लगेगा कि props change हो गए हैं, जिससे child component बेवजह heavy computational cycle चलाएगा।

सटीक समाधान (The Fix):

इस render logic को एक regular instance method (या component function hook inside useCallback) के रूप में bind करें, जिससे static references reference memory leak और useless calculation prevent कर सकें:

import React, { useCallback } from 'react';

const MyParentComponent = () => {
  // Callback Hook references hold करेगा
  const renderMousePointer = useCallback((coords) => {
    return <DisplayCoords coords={coords} />;
  }, []);

  return <MouseTracker render={renderMousePointer} />;
};

Enter fullscreen mode Exit fullscreen mode

2. "TypeError: render is not a function"

यह error अक्सर तब आती है जब आप wrapper component का code strict types के बिना लिखते हैं और parent structure पर render target dynamic logic props pass करना भूल जाते हैं।

सटीक समाधान (The Fix):

हमेशा props को sanitize करें या components के default setup parameters declare करके fallback functions provide करें:

// Using Prop-Types to secure function logic structures
import PropTypes from 'prop-types';

const MouseTracker = ({ render }) => {
  // logic...
  return render ? render(stateCoords) : null;
};

MouseTracker.propTypes = {
  render: PropTypes.func.isRequired
};

Enter fullscreen mode Exit fullscreen mode

Toh dosto, humne aaj seekha...

तो दोस्तों, आज के इस interactive masterclass tutorial में हमने सीखा कि React Render Props Pattern क्या है, यह कैसे हमारी state reuse problem को चुटकियों में solve करता है, और इसे proper architecture flow के साथ clean React syntax में कैसे implement किया जाता है।

भले ही आज की तारीख में Custom Hooks ने React community का पूरा focus खींचा हो, लेकिन dynamic wrapper widgets, library development (जैसे Formik या React Router v4) और conditional context propagation में Render Props Pattern आज भी एक solid और reliable design standard माना जाता है।

Frequently Asked Questions (FAQs)

Q1: क्या React Hooks आने के बाद Render Props Pattern पूरी तरह obsolete (बेकार) हो गया है?
नहीं, Hooks ज्यादातर simple logic share करने के लिए बेस्ट हैं, लेकिन जब आपको logical wrapper components (जैसे Router wrapper or state layouts) की custom UI render runtime dynamic setup control करनी हो, तब Render Props pattern आज भी React engineering में dominant use-case रखता है।
Q2: क्या Render Props Pattern का use करके React Performance पर बुरा असर पड़ता है?
यदि आप dynamic inputs inline anonymous rendering handlers utilize करते हैं, तो state changes पर reference rendering calculation mismatch loads generate होते हैं। हालाँकि, useCallback हुक या simple structured instance method implementation से इसे 100% optimized रखा जा सकता है।
Q3: React Children as Render Props क्या है?
जब हम nested JSX methods pass करने के लिए standard render prop variables custom tags use न करके, JSX component parameters के direct function callbacks structure reference write करते हैं, तो उसे context propagation rendering methods logic child implementation parameters कहते हैं।
Q4: Higher-Order Components (HOC) और Render Props में से कौन सा बेहतर है?
HOC, components code layers setup levels nested wrapper classes logic nested complications structures create करते हैं। Render props explicit mapping coordinates logic parameter levels bypass structures flow handle करने के कारण control tracking structure dynamic logic debugging points process simpler बनाता है।
Q5: क्या मैं Render prop function का नाम "render" के अलावा कुछ और रख सकता हूँ?
हाँ, बिल्कुल! यह absolute open architecture structure validation rules है। आप prop name design parameter specifications settings key render, children, generateBody, viewElement, configureComponent, या custom dynamic values handle configuration structures provide करके create customize logic layers inject can control dynamic state outputs directly can render variables!

Top comments (0)