उत्पादन में रिएक्ट हुक का उपयोग करने के लिए 5 सर्वोत्तम अभ्यास

लेख के लेखक, जिसका अनुवाद आज हम प्रकाशित कर रहे हैं, का कहना है कि commercetools ने 2019 की शुरुआत में React के हुक को अपनाया - प्रतिक्रिया 16.8.0 में उनकी उपस्थिति के समय। तब से, कंपनी के प्रोग्रामर लगातार अपने कोड को संसाधित कर रहे हैं, इसे हुक में अनुवाद कर रहे हैं। रिएक्ट हुक आपको घटक राज्य का उपयोग करने और कक्षाओं का उपयोग किए बिना अन्य रिएक्ट सुविधाओं का उपयोग करने की अनुमति देता है। हुक का उपयोग करते हुए, आप कर सकते हैं, जब कार्यात्मक घटकों के साथ काम करते हैं, घटक जीवन चक्र की घटनाओं से "कनेक्ट" करते हैं और उनके राज्य में परिवर्तन का जवाब देते हैं।



हुक लागू करने के परिणामों के बारे में संक्षेप में


यदि संक्षेप में हम बात करते हैं कि हुक ने हमें क्या दिया, तो यह पता चला कि उन्होंने घटकों से तर्क को निकालने और विभिन्न क्षमताओं की संरचना को सुविधाजनक बनाने के द्वारा कोड आधार को सरल बनाने में मदद की। इसके अलावा, हुक के उपयोग ने इस तथ्य को जन्म दिया है कि हमने बहुत कुछ सीखा है। उदाहरण के लिए, मौजूदा कार्यक्षमता के निरंतर सुधार के माध्यम से अपने कोड को बेहतर कैसे बनाया जाए। हमें यकीन है कि हम रिएक्ट हुक के साथ काम करना जारी रखते हुए कई और दिलचस्प चीजें सीखेंगे।

हुक कार्यान्वयन की ताकत


यहाँ हुक का परिचय हमें दिया गया है:

  • कोड पठनीयता में सुधार। यह पहले की तुलना में छोटे घटक पेड़ों के उपयोग के लिए संभव है। इस तरह के घटक पेड़ों के निर्माण को प्रतिपादन गुणों और उच्च-क्रम के घटकों को छोड़ने की हमारी इच्छा से सुविधा होती है।
  • कोड डिबगिंग क्षमताओं में सुधार। हमारे पास हमारे निपटान में कोड के एक बेहतर दृश्य प्रतिनिधित्व और रिएक्टर डेवलपर टूल द्वारा प्रदान की गई अतिरिक्त डिबगिंग जानकारी थी।
  • परियोजना की प्रतिरूपकता में सुधार। हुक की कार्यात्मक प्रकृति के कारण, बार-बार उपयोग के लिए उपयुक्त तर्क बनाने और लागू करने की प्रक्रिया को सरल बनाया गया है।
  • जिम्मेदारियों का अलग होना। रिएक्ट घटक इंटरफ़ेस तत्वों की उपस्थिति के लिए जिम्मेदार हैं, और हुक एन्कैप्सुलेटेड प्रोग्राम लॉजिक तक पहुंच प्रदान करते हैं।

अब हम उत्पादन में हुक के उपयोग पर अपनी सिफारिशें साझा करना चाहते हैं।

1. समय पर घटकों से हुक निकालते हैं और कस्टम हुक बनाते हैं


कार्यात्मक घटकों में हुक का उपयोग करना शुरू करना बहुत आसान है। उदाहरण के लिए, हमने जल्दी से कहीं React.useState, कहीं React.useEffectऔर आवेदन किया - और अपना काम करना जारी रखा। यह दृष्टिकोण, हालांकि, उन सभी अवसरों का पूरा लाभ उठाने की अनुमति नहीं देता है जो हुक देने में सक्षम हैं। पेश React.useStateएक छोटा सा के रूप में use<StateName>State, और React.useEffect- के रूप में use<EffectName>Effect, हम निम्नलिखित को प्राप्त करने में सक्षम थे:

  1. नियमित हुक के मुकाबले घटक छोटे होते हैं।
  2. विभिन्न घटकों में हुक का पुन: उपयोग किया जा सकता है।
  3. , React, , . , State<StateName> State. React.useState, .

पुनः प्राप्त करने वाले हुक इस तथ्य में भी योगदान करते हैं कि पुन: प्रयोज्य और साझा तर्क आवेदन के विभिन्न हिस्सों में अधिक दिखाई देता है। यदि आप केवल घटक कोड में निर्मित हुक का उपयोग करते हैं, तो समान या डुप्लिकेट तर्क नोटिस करना अधिक कठिन है। परिणामी हुक आकार में छोटे हो सकते हैं और बहुत कम कोड होते हैं - जैसे useToggleState। दूसरी ओर, बड़े हुक, जैसे useProductFetcher, अब अधिक कार्यक्षमता शामिल कर सकते हैं। इन दोनों ने हमें प्रतिक्रिया घटकों के आकार को कम करके कोड आधार को सरल बनाने में मदद की।

निम्नलिखित उदाहरण तत्वों के चयन को नियंत्रित करने के लिए डिज़ाइन किया गया एक छोटा रिएक्ट हुक बनाता है। इस कार्यक्षमता को एनकैप्सुलेट करने के लाभ स्पष्ट हो जाते हैं, जब आपको पता चलता है कि इस तरह के तर्क का उपयोग कितनी बार किया जाता है। उदाहरण के लिए, किसी सूची से आदेशों का एक समूह चुनने के लिए।

//  

function Component() {
    const [selected, setSelected] = React.useState()
    const select = React.useCallback(id => setSelected(/** ... */), [
        selected,
        setSelect
    ])

    return <List selectedIds={selected} onSelect={id => select(id)} />
}

//   

const useSelection = () => {
    const [selected, setSelected] = React.useState()
    const select = React.useCallback(id => setSelected(/** ... */), [
        selected,
        setSelect
    ])

    return [selected, select]
}

function Component() {
    const [selected, select] = useSelection()

    return <List selectedIds={selected} onSelect={id => select(id)} />
}

2. React.useDebugValue के लाभों के बारे में


मानक React.useDebugValue हुक अल्प-ज्ञात प्रतिक्रिया सुविधाओं को संदर्भित करता है। यह हुक कोड के डिबगिंग के दौरान डेवलपर की मदद कर सकता है; यह साझा-एक्सेस हुक में इसका उपयोग करने के लिए उपयोगी हो सकता है। ये उपयोगकर्ता हुक हैं जो अनुप्रयोग के कई घटकों में उपयोग किए जाते हैं। हालांकि, useDebugValueसभी उपयोगकर्ता हुक में इसका उपयोग करने की अनुशंसा नहीं की जाती है, क्योंकि अंतर्निहित हुक पहले से ही मानक डिबग मानों को लॉग करते हैं।

एक कस्टम हुक बनाने की कल्पना करें जो एप्लिकेशन की कुछ विशेषता को सक्षम करने की आवश्यकता के बारे में निर्णय लेने के लिए डिज़ाइन किया गया हो। एप्लिकेशन स्टेट डेटा जिस पर निर्णय आधारित है, विभिन्न स्रोतों से आ सकता है। उन्हें एक प्रतिक्रिया संदर्भ वस्तु में संग्रहीत किया जा सकता है, जिसके माध्यम से आयोजित किया जाता है React.useContext

डिबगिंग में डेवलपर की मदद करने के लिए, रिएक्टर डेवलपर टूल के साथ काम करते समय, विश्लेषण किए गए ध्वज नाम ( flagName) और ध्वज मूल्य के संस्करण ( ) के बारे में जानना उपयोगी हो सकता है flagVariationइस मामले में, एक छोटे हुक का उपयोग करने से हमें मदद मिल सकती है React.useDebugValue:

export default function useFeatureToggle(flagName, flagVariation = true) {
    const flags = React.useContext(FlagsContext)
    const isFeatureEnabled = getIsFeatureEnabled(flagName, flagVariation)(flags)

    React.useDebugValue({
        flagName,
        flagVariation,
        isEnabled: isFeatureEnabled
    })

    return isFeatureEnabled
}

अब, रिएक्टर डेवलपर के टूल के साथ काम करते हुए, हम फ्लैग वैल्यू के विकल्प के बारे में, फ्लैग नाम के बारे में जानकारी देख सकते हैं, और हमारे लिए ब्याज की सुविधा चालू है या नहीं।


React.useDebugValue हुक लगाने के बाद रिएक्टर डेवलपर टूल के साथ काम करना

कृपया ध्यान दें कि ऐसे मामलों में जब उपयोगकर्ता हुक मानक हुक का उपयोग करते हैं जैसेReact.useStateयाReact.useRef, ऐसे हुक पहले से ही संबंधित स्थिति या रेफ-ऑब्जेक्ट डेटा लॉग करते हैं। परिणामस्वरूप, यहां व्यू कंस्ट्रक्शन का उपयोगReact.useDebugValue({ state })विशेष रूप से उपयोगी नहीं है।

3. हुक का संयोजन और रचना


जब हमने अपने काम में हुक लागू करना शुरू किया और घटकों में अधिक से अधिक हुक का उपयोग करना शुरू किया, तो यह जल्दी से पता चला कि 5-10 हुक एक ही घटक में मौजूद हो सकते हैं। इस मामले में, विभिन्न प्रकार के हुक का उपयोग किया गया था। उदाहरण के लिए, हम 2-3 हुक का उपयोग कर सकते हैं React.useState, फिर एक हुक React.useContext(कहते हैं, सक्रिय उपयोगकर्ता के बारे में जानकारी प्राप्त करने के लिए), एक हुक React.useEffect, और अन्य पुस्तकालयों से भी प्रतिक्रिया-राउटर या रिएक्शन-इंटल जैसे हुक

उपरोक्त बार-बार दोहराया गया था, परिणामस्वरूप, यहां तक ​​कि बहुत छोटे घटक इतने कॉम्पैक्ट नहीं थे। इससे बचने के लिए, हमने इन व्यक्तिगत हुक को उपयोगकर्ता हुक में निकालना शुरू किया, जिनमें से उपकरण घटक या कुछ अनुप्रयोग क्षमता पर निर्भर था।

एक आदेश बनाने के उद्देश्य से एक आवेदन तंत्र की कल्पना करें। इस तंत्र को विकसित करते समय, कई घटकों का उपयोग किया गया, साथ ही साथ विभिन्न प्रकार के हुक भी। इन हुकों को कस्टम हुक के रूप में जोड़ा जा सकता है, जिससे घटकों की उपयोगिता बढ़ जाती है। यहां एक हुक में छोटे हुक के सेट के संयोजन का एक उदाहरण है।

function OrderCreate() {
    const {
        orderCreater,
        orderFetcher,
        applicationContext,
        goToNextStep,
        pendingOrder,
        updatePendingChanges,
        revertPendingChanges
    } = useOrderCreate()

    return (/** ...children */)
}

4. React.useReducer और React.useState की तुलना


हमने अक्सर React.useStateघटकों की स्थिति के साथ काम करने के लिए एक मानक हुक के रूप में सहारा लिया । हालांकि, समय के साथ, घटक की स्थिति को जटिल करने की आवश्यकता हो सकती है, जो घटक की नई आवश्यकताओं पर निर्भर करता है, जैसे कि राज्य में कई मूल्यों की उपस्थिति। कुछ मामलों में, उपयोग React.useReducerकई मूल्यों का उपयोग करने और राज्य को अपडेट करने के तर्क को सरल बनाने की आवश्यकता से बचने में मदद कर सकता है। HTTP अनुरोध और प्रतिक्रिया प्राप्त करते समय राज्य प्रबंधन की कल्पना करें। ऐसा करने के लिए, आपको मानों के साथ काम करने की आवश्यकता हो सकती है isLoading, जैसे dataऔरerrorइसके बजाय, राज्य को एक reducer का उपयोग करके नियंत्रित किया जा सकता है, इसके निपटान में राज्य परिवर्तनों का प्रबंधन करने के लिए विभिन्न क्रियाएं होती हैं। यह दृष्टिकोण, आदर्श रूप से, डेवलपर को राज्य मशीन के रूप में इंटरफ़ेस की स्थिति का अनुभव करने के लिए प्रोत्साहित करता है।

प्रेषित React.useReducerरेड्यूसर Redux में उपयोग किए जाने वाले रेड्यूसर के समान है , जहां सिस्टम कार्रवाई की वर्तमान स्थिति प्राप्त करता है और अगले राज्य को वापस करना चाहिए। कार्रवाई में इसके प्रकार, साथ ही अगले राज्य के गठन के आधार पर डेटा शामिल है। यहाँ एक सरल रेड्यूसर का उदाहरण दिया गया है जो एक निश्चित काउंटर को नियंत्रित करने के लिए डिज़ाइन किया गया है:

const initialState = 0;
const reducer = (state, action) => {
    switch (action) {
        case 'increment': return state + 1;
        case 'decrement': return state - 1;
        case 'reset': return 0;
        default: throw new Error('Unexpected action');
    }
};

इस रिड्यूसर को आइसोलेशन में टेस्ट किया जा सकता है और फिर कंपोनेंट में इसका इस्तेमाल किया जा सकता है React.useReducer:

function Component() {
    const [count, dispatch] = React.useReducer(reducer, initialState);

    return (
        <div>
            {count}
            <button onClick={() => dispatch('increment')}>+1</button>
            <button onClick={() => dispatch('decrement')}>-1</button>
            <button onClick={() => dispatch('reset')}>reset</button>
        </div>
    );
};

यहां हम पिछले तीन खंडों में जांच की गई चीज़ों को लागू कर सकते हैं, अर्थात हम सब कुछ निकाल सकते हैं useCounterReducerयह एक इंटरफ़ेस तत्व की उपस्थिति का वर्णन करने वाले घटक से कार्रवाई प्रकार की जानकारी छिपाकर कोड में सुधार करेगा। परिणामस्वरूप, यह घटक में कार्यान्वयन विवरण के रिसाव को रोकने में मदद करेगा, और हमें डिबगिंग कोड के लिए अतिरिक्त अवसर भी देगा। यहाँ परिणामी कस्टम हुक और इसका उपयोग करने वाला घटक कैसा दिखेगा:

const CounterActionTypes = {
    Increment: 'increment',
    Decrement: 'decrement',
    Reset: 'reset',
}

const useCounterReducer = (initialState) => {
    const [count, dispatch] = React.useReducer(reducer, initialState);

    const increment = React.useCallback(() => dispatch(CounterActionTypes.Increment));
    const decrement = React.useCallback(() => dispatch(CounterActionTypes.Decrement));
    const reset = React.useCallback(() => dispatch(CounterActionTypes.Reset));

    return {
        count,
        increment,
        decrement
    }
}

function Component() {
    const {count, increment} = useCounterReducer(0);

    return (
        <div>
            {count}
            <button onClick={increment}>+1</button>
        </div>
    );
};

5. हुक का क्रमिक कार्यान्वयन


पहली नज़र में, धीरे-धीरे हुक शुरू करने का विचार पूरी तरह से तर्कसंगत नहीं लग सकता है, लेकिन यहां मैं सुझाव देता हूं कि जो लोग ऐसा सोचते हैं वे बस मेरे तर्क का पालन करते हैं। समय के साथ, विभिन्न पैटर्न कोडबेस में एप्लिकेशन ढूंढते हैं। हमारे मामले में, इन पैटर्नों में उच्च-क्रम के घटक, रेंडरिंग गुण, और अब हुक शामिल हैं। एक परियोजना को नए पैटर्न में अनुवाद करते समय, डेवलपर्स तुरंत सभी कोड को फिर से लिखना नहीं चाहते हैं, जो सामान्य रूप से, लगभग असंभव है। नतीजतन, आपको प्रोजेक्ट को रिएक्ट हुक में स्थानांतरित करने के लिए एक योजना विकसित करने की आवश्यकता है, जो कोड में बड़े बदलावों के लिए प्रदान नहीं करता है। यह कार्य बहुत कठिन हो सकता है, क्योंकि कोड में बदलाव करने से आमतौर पर इसके आकार और जटिलता में वृद्धि होती है। हुक लगाने से, हम इससे बचने का प्रयास करते हैं।

हमारा कोडबेस क्लास-आधारित घटकों और कार्यात्मक घटकों का उपयोग करता है। भले ही किसी निश्चित स्थिति में किस घटक का उपयोग किया गया था, हमने रिएक्ट हुक के माध्यम से तर्क साझा करने की मांग की। सबसे पहले, हम तर्क को हुक में लागू करते हैं (या उनमें कुछ तंत्रों के मौजूदा कार्यान्वयन को दोहराते हैं), फिर एक उच्च क्रम के छोटे घटक बनाते हैं, जिसके अंदर इन हुक का उपयोग किया जाता है। उसके बाद, क्लास-आधारित घटकों को बनाने के लिए इन उच्च-क्रम वाले घटकों का उपयोग किया जाता है। परिणामस्वरूप, हमारे पास एक स्थान पर स्थित हमारे निपटान तर्क है, जिसका उपयोग विभिन्न प्रकार के घटकों में किया जा सकता है। यहाँ उच्च क्रम घटकों के माध्यम से घटकों में हुक कार्यक्षमता को लागू करने का एक उदाहरण है।

export const injectTracking = (propName = 'tracking') => WrappedComponent => {
    const WithTracking = props => {
        const tracking = useTracking();

        const trackingProp = {
            [propName]: tracking,
        };

        return <WrappedComponent {...props} {...trackingProp} />;
    };

    WithTracking.displayName = wrapDisplayName(WrappedComponent, 'withTracking');

    return WithTracking;
};

export default injectTracking;

यह useTrackingएक घटक में हुक कार्यक्षमता के कार्यान्वयन को दर्शाता है WrappedComponentयह, वैसे, हमें, अन्य चीजों के अलावा, सिस्टम के पुराने हिस्सों में हुक और पुनर्लेखन परीक्षणों को लागू करने के कार्यों को अलग करने की अनुमति देता है। इस दृष्टिकोण के साथ, कोड आधार के सभी हिस्सों में हुक का उपयोग करने के लिए हमारे पास अभी भी हमारे निपटान तंत्र हैं।

सारांश


यहां कुछ उदाहरण दिए गए थे कि कैसे रिएक्ट हुक का उपयोग करने से हमारे कोडबेस में सुधार हुआ। हमें उम्मीद है कि हुक आपकी परियोजना को भी लाभान्वित कर सकते हैं।

प्रिय पाठकों! क्या आप रिएक्ट हुक का उपयोग करते हैं?


All Articles