रिएक्ट एप्लिकेशन में सेवाएं देना


176

मैं कोणीय दुनिया से आ रहा हूं जहां मैं एक सेवा / कारखाने में तर्क निकाल सकता हूं और अपने नियंत्रकों में उनका उपभोग कर सकता हूं।

मैं यह समझने की कोशिश कर रहा हूं कि मैं रिएक्ट एप्लिकेशन में कैसे प्राप्त कर सकता हूं।

मान लीजिए कि मेरे पास एक घटक है जो उपयोगकर्ता के पासवर्ड इनपुट (यह शक्ति है) को मान्य करता है। यह तर्क बहुत जटिल है इसलिए मैं इसे उस घटक में नहीं लिखना चाहता हूँ जो यह स्व।

मुझे यह तर्क कहां लिखना चाहिए? एक दुकान में अगर मैं प्रवाह का उपयोग कर रहा हूँ? या कोई बेहतर विकल्प है?


आप एक पैकेज का उपयोग कर सकते हैं और देख सकते हैं कि वे कैसे कर रहे हैं - npmjs.com/package/react-password-strength-meter
James111

11
पासवर्ड की ताकत सिर्फ एक उदाहरण है। मैं एक अधिक सामान्य सर्वोत्तम अभ्यास की तलाश कर रहा हूं
डेनिस नेरुश

आपको इसे सर्वर साइड में करना पड़ सकता है?
जेम्स ११

2
नहीं। केवल ग्राहक पक्ष तर्क जो सीधे घटक में नहीं होना चाहिए। पासवर्ड शक्ति परीक्षक सिर्फ एक उदाहरण है
डेनिस नेरुश

4
यदि आपके पास ऐसे कई कार्य हैं, तो आप उन्हें एक सहायक फ़ाइल में संग्रहीत कर सकते हैं और उपयोग के लिए बस अपने घटक फ़ाइल में इसकी आवश्यकता होती है। यदि यह एक एकल कार्य है जो पूरी तरह से उस घटक के लिए प्रासंगिक है, तो संभवतः इसे जीना चाहिए कोई फर्क नहीं पड़ता जटिलता।
जेसी कर्णघन

जवाबों:


60

पहला उत्तर वर्तमान कंटेनर बनाम प्रस्तुतकर्ता प्रतिमान को प्रतिबिंबित नहीं करता है ।

यदि आपको कुछ करने की आवश्यकता है, जैसे पासवर्ड को मान्य करना, तो संभवतः आपके पास एक फ़ंक्शन होगा जो इसे करता है। आप उस कार्य को अपने पुन: प्रयोज्य दृश्य के रूप में एक प्रस्ताव के रूप में पारित करेंगे।

कंटेनर

तो, इसका सही तरीका यह है कि एक ValidatorContainer लिखना है, जिसमें एक संपत्ति के रूप में वह कार्य होगा, और उसमें फॉर्म को लपेटकर, बच्चे को सही प्रॉप्स पास करना होगा। जब यह आपके विचार में आता है, तो आपका सत्यापनकर्ता कंटेनर आपके दृश्य को लपेटता है और दृश्य कंटेनर तर्क का उपभोग करता है।

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

प्रदाताओं

यदि थोड़ा और विन्यास आवश्यक है, तो आप एक प्रदाता / उपभोक्ता मॉडल का उपयोग कर सकते हैं। एक प्रदाता एक उच्च स्तरीय घटक है जो शीर्ष एप्लिकेशन ऑब्जेक्ट (आप जिसे माउंट करते हैं) के नीचे और उसके करीब कहीं लपेटता है और संदर्भ एपीआई के लिए खुद का एक हिस्सा या शीर्ष परत में कॉन्फ़िगर की गई संपत्ति की आपूर्ति करता है। फिर मैंने अपने कंटेनर तत्वों को संदर्भ का उपभोग करने के लिए सेट किया।

माता-पिता / बच्चे के संदर्भ संबंध एक-दूसरे के पास नहीं होते हैं, बस बच्चे को किसी तरह से उतरना पड़ता है। इस तरह Redux स्टोर्स और रिएक्ट राउटर फंक्शन। मैंने इसे अपने बाकी कंटेनरों के लिए एक रूट रेस्टफुल संदर्भ प्रदान करने के लिए उपयोग किया है (यदि मैं अपना खुद का प्रदान नहीं करता हूं)।

(नोट: संदर्भ एपीआई डॉक्स में प्रयोगात्मक रूप से चिह्नित है, लेकिन मुझे नहीं लगता कि यह किसी भी अधिक है, यह देखते हुए कि इसका उपयोग क्या है)।

//An example of a Provider component, takes a preconfigured restful.js
//object and makes it available anywhere in the application
export default class RestfulProvider extends React.Component {
	constructor(props){
		super(props);

		if(!("restful" in props)){
			throw Error("Restful service must be provided");
		}
	}

	getChildContext(){
		return {
			api: this.props.restful
		};
	}

	render() {
		return this.props.children;
	}
}

RestfulProvider.childContextTypes = {
	api: React.PropTypes.object
};

मध्यस्थ

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

इस तरह, मैं अपने restful.js ऑब्जेक्ट को मिडलवेयर में इंजेक्ट कर सकता हूं और अपने कंटेनर के तरीकों को स्वतंत्र कार्यों के साथ बदल सकता हूं। मैं अभी भी एक कंटेनर घटक की जरूरत है कि प्रपत्र दृश्य परत को कार्रवाई प्रदान करने के लिए, लेकिन कनेक्ट () और mapDispatchToProps ने मुझे वहां कवर किया है।

नया v4 प्रतिक्रिया-राउटर-रेडक्स इतिहास की स्थिति को प्रभावित करने के लिए इस पद्धति का उपयोग करता है, उदाहरण के लिए।

//Example middleware from react-router-redux
//History is our service here and actions change it.

import { CALL_HISTORY_METHOD } from './actions'

/**
 * This middleware captures CALL_HISTORY_METHOD actions to redirect to the
 * provided history object. This will prevent these actions from reaching your
 * reducer or any middleware that comes after this one.
 */
export default function routerMiddleware(history) {
  return () => next => action => {
    if (action.type !== CALL_HISTORY_METHOD) {
      return next(action)
    }

    const { payload: { method, args } } = action
    history[method](...args)
  }
}


महान जवाब दोस्त, आपने मुझे 8 दिमाग खराब करने से रोका) KUDOS !!
csomakk

कंटेनर उदाहरण के लिए उपयोग क्या है?
sensei

मैं इसकी वकालत नहीं कर रहा हूं, लेकिन यदि आप सेवा लोकेटर पथ (कोणीय के समान कुछ) पर जाना चाहते हैं, तो आप कुछ ऐसे "इंजेक्टर / कंटेनर" प्रदाता जोड़ सकते हैं जिन्हें आप सेवाओं से हल करते हैं (पहले से पंजीकृत हैं)।
Eddiewould

रेस्क्यू हुक बचाव के लिए आता है। हुक के साथ आप एक वर्ग लिखे बिना पुन: प्रयोज्य तर्क लिख सकते हैं। reactjs.org/docs/…
राजा मलिक

102

मुद्दा बेहद सरल हो जाता है जब आपको पता चलता है कि एक कोणीय सेवा सिर्फ एक वस्तु है जो संदर्भ-स्वतंत्र तरीकों का एक सेट वितरित करती है। यह सिर्फ कोणीय DI तंत्र है जो इसे और अधिक जटिल बनाता है। DI उपयोगी है क्योंकि यह आपके लिए उदाहरण बनाने और बनाए रखने का ध्यान रखता है लेकिन आपको वास्तव में इसकी आवश्यकता नहीं है।

एक लोकप्रिय AJAX पुस्तकालय पर विचार करें, जिसका नाम axios (जिसे आपने शायद सुना हो):

import axios from "axios";
axios.post(...);

क्या यह एक सेवा के रूप में व्यवहार नहीं करता है? यह कुछ विशिष्ट तर्क के लिए जिम्मेदार तरीकों का एक सेट प्रदान करता है और मुख्य कोड से स्वतंत्र है।

आपका उदाहरण मामला आपके इनपुट को मान्य करने के लिए तरीकों का एक अलग सेट बनाने के बारे में था (उदाहरण के लिए पासवर्ड की ताकत की जाँच करना)। कुछ ने इन तरीकों को उन घटकों के अंदर रखने का सुझाव दिया जो मेरे लिए स्पष्ट रूप से एक विरोधी पैटर्न है। क्या होगा यदि सत्यापन में एक्सएचआर बैकएंड कॉल या जटिल गणना करना और प्रसंस्करण शामिल है? क्या आप माउस क्लिक हैंडलर और अन्य UI विशिष्ट सामान के साथ इस तर्क को मिलाएंगे? बकवास। कंटेनर / HOC दृष्टिकोण के साथ भी ऐसा ही है। सिर्फ एक विधि जोड़ने के लिए अपने घटक को लपेटना जो यह जांच करेगा कि क्या मूल्य में एक अंक है? आ जाओ।

मैं सिर्फ 'ValidationService.js' नामक एक नई फ़ाइल बनाऊंगा और इसे निम्नानुसार व्यवस्थित करूंगा:

const ValidationService = {
    firstValidationMethod: function(value) {
        //inspect the value
    },

    secondValidationMethod: function(value) {
        //inspect the value
    }
};

export default ValidationService;

फिर अपने घटक में:

import ValidationService from "./services/ValidationService.js";

...

//inside the component
yourInputChangeHandler(event) {

    if(!ValidationService.firstValidationMethod(event.target.value) {
        //show a validation warning
        return false;
    }
    //proceed
}

इस सेवा का उपयोग आप कहीं से भी कर सकते हैं। यदि सत्यापन नियम बदलते हैं तो आपको केवल ValidationService.js फ़ाइल पर ध्यान केंद्रित करने की आवश्यकता है।

आपको अधिक जटिल सेवा की आवश्यकता हो सकती है जो अन्य सेवाओं पर निर्भर करती है। इस स्थिति में आपकी सेवा फ़ाइल किसी स्थिर ऑब्जेक्ट के बजाय एक क्लास कंस्ट्रक्टर को वापस कर सकती है ताकि आप घटक में स्वयं द्वारा ऑब्जेक्ट का एक उदाहरण बना सकें। आप यह सुनिश्चित करने के लिए एक साधारण सिंगलटन को लागू करने पर भी विचार कर सकते हैं कि पूरे एप्लिकेशन के उपयोग में सेवा ऑब्जेक्ट का केवल एक ही उदाहरण है।


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

6
+1 - अच्छा जवाब अगर आप केवल सेवाओं का उपयोग कर रहे हैं जो फ़ंक्शन प्रदान करते हैं। हालांकि , एंगुलर की सेवा ऐसी कक्षाएं हैं जो एक बार परिभाषित की जाती हैं, इस प्रकार केवल कार्य देने से अधिक सुविधाएँ प्रदान करती हैं। आप उदाहरण के लिए, वस्तुओं को सेवा वर्ग पैरामीटर के रूप में कैश कर सकते हैं।
नीनो फीलु

6
यह वास्तविक उत्तर होना चाहिए, और ऊपर जटिल प्रतिक्रिया नहीं
21115 पर user1807334

1
यह एक अच्छा जवाब है, सिवाय इसके कि यह "प्रतिक्रियाशील" नहीं है। DOM सेवा के भीतर परिवर्तनशील परिवर्तनों पर अपडेट नहीं करेगा।
डिफ़ेक्टो

9
हालांकि निर्भरता इंजेक्शन के बारे में क्या? जब तक आप इसे किसी भी तरह से इंजेक्ट नहीं करते हैं, तब तक आपके घटक में यह सेवा असंभव है। शायद एक शीर्ष-स्तरीय "कंटेनर" वैश्विक वस्तु है जिसमें एक क्षेत्र के रूप में प्रत्येक सेवा है, इसके चारों ओर मिल जाएगी। फिर अपने परीक्षणों में, आप उन सेवाओं के लिए कंटेनर फ़ील्ड को मॉक के साथ ओवरराइड कर सकते हैं जिन्हें आप मॉक करना चाहते हैं।
मेनेहुन्ने 23

34

मुझे कई घटकों में साझा करने के लिए कुछ स्वरूपण तर्क की आवश्यकता थी और एक कोणीय डेवलपर के रूप में भी स्वाभाविक रूप से एक सेवा की ओर झुकाव हुआ।

मैंने तर्क को एक अलग फ़ाइल में डालकर साझा किया

function format(input) {
    //convert input to output
    return output;
}

module.exports = {
    format: format
};

और फिर इसे एक मॉड्यूल के रूप में आयात किया

import formatter from '../services/formatter.service';

//then in component

    render() {

        return formatter.format(this.props.data);
    }

8
यह एक अच्छा विचार है जैसा कि रिएक्ट दस्तावेज़ में भी बताया गया है: reactjs.org/docs/composition-vs-inheritance.html यदि आप घटकों के बीच गैर-UI कार्यक्षमता का पुन: उपयोग करना चाहते हैं, तो हम इसे एक अलग जावास्क्रिप्ट मॉड्यूल में निकालने का सुझाव देते हैं। अवयव इसे आयात कर सकते हैं और उस कार्य, वस्तु, या एक वर्ग का उपयोग कर सकते हैं, बिना इसका विस्तार किए।
user3426603

यह वास्तव में यहाँ केवल एक ही मतलब है।
आर्टेम नोविकोव

33

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

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

लेकिन उन मामलों में से किसी में, यह हमेशा कुछ पाठ इनपुट फ़ील्ड से बंधा होने वाला है। तो यह वह जगह है जहाँ इसे युग्मित किया जाना चाहिए।

एक बहुत छोटा रिएक्ट घटक बनाएं जिसमें पूरी तरह से एक इनपुट फ़ील्ड और संबंधित मान्यता तर्क हैं। इनपुट कि सभी रूपों के भीतर घटक है कि एक पासवर्ड इनपुट करना चाहते हो सकता है।

यह अनिवार्य रूप से तर्क के लिए एक सेवा / कारखाना होने के समान परिणाम है, लेकिन आप इसे सीधे इनपुट पर युग्मित कर रहे हैं। तो अब आपको उस फ़ंक्शन को यह बताने की आवश्यकता नहीं है कि यह सत्यापन इनपुट कहां देखना है, क्योंकि यह स्थायी रूप से एक साथ बंधा हुआ है।


11
क्या यह युगल तर्क और यूआई के लिए बुरा अभ्यास है। तर्क बदलने के लिए मुझे घटक को स्पर्श करना होगा
डेनिस नेरुश

14
मौलिक रूप से चुनौतियों का सामना करें जो कि आप बना रहे हैं। यह पारंपरिक एमवीसी वास्तुकला के विपरीत है। यह वीडियो यह समझाने का एक बहुत अच्छा काम करता है कि ऐसा क्यों है (प्रासंगिक अनुभाग 2 मिनट के आसपास शुरू होता है)।
जेक रॉबी

8
क्या होगा यदि एक ही सत्यापन तर्क को एक पाठ क्षेत्र तत्व पर लागू करने की आवश्यकता है? तर्क को अभी भी एक साझा फ़ाइल में निकालने की आवश्यकता है। मुझे नहीं लगता कि आउट ऑफ बॉक्स कोई प्रतिक्रिया लाइब्रेरी से कोई समानता है। कोणीय सेवा इंजेक्टेबल्स हैं, और कोणीय रूपरेखा निर्भरता इंजेक्शन डिजाइन पैटर्न के शीर्ष पर बनाई गई है, जो कोणीय द्वारा प्रबंधित निर्भरता के उदाहरणों की अनुमति देती है। जब किसी सेवा को इंजेक्ट किया जाता है, तो आमतौर पर प्रदान किए गए दायरे में एक सिंगलटन होता है, उसी सेवा को रिएक्ट में रखने के लिए, आवेदन के लिए एक 3 पार्टी डीआई लिब की आवश्यकता होती है।
डाउनहिल्स्की

15
@ ग्रेविटीप्लानक्स मैं रिएक्ट का उपयोग करके आनंद लेता हूं। यह कोणीय पैटर्न नहीं है, यह सॉफ्टवेयर डिज़ाइन पैटर्न है। मैं उन चीजों को उधार लेना पसंद करता हूं, जिन्हें मैं अन्य अच्छे हिस्सों से पसंद करता हूं।
Downhillski

1
@ मिक्कीपुरी ES6 मॉड्यूल डिपेंडेंसी इंजेक्शन के समान नहीं है।
Spock

12

मैं Angular.js क्षेत्र से भी आया और React.js में सेवाएँ और कारखाने अधिक सरल हैं।

आप मेरी तरह सादे कार्यों या कक्षाओं, कॉलबैक शैली और घटना Mobx का उपयोग कर सकते हैं :)

// Here we have Service class > dont forget that in JS class is Function
class HttpService {
  constructor() {
    this.data = "Hello data from HttpService";
    this.getData = this.getData.bind(this);
  }

  getData() {
    return this.data;
  }
}


// Making Instance of class > it's object now
const http = new HttpService();


// Here is React Class extended By React
class ReactApp extends React.Component {
  state = {
    data: ""
  };

  componentDidMount() {
    const data = http.getData();

    this.setState({
      data: data
    });
  }

  render() {
    return <div>{this.state.data}</div>;
  }
}

ReactDOM.render(<ReactApp />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  
  <div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

</body>
</html>

यहाँ सरल उदाहरण है:


React.js यूआई घटकों को प्रस्तुत करने और व्यवस्थित करने के लिए यूआई लाइब्रेरी है। जब ऐसी सेवाओं की बात आती है जो हमें अतिरिक्त कार्यक्षमताओं को जोड़ने में मदद कर सकती हैं तो हमें कार्यों, कार्यात्मक वस्तुओं या कक्षाओं के संग्रह बनाने चाहिए। मुझे कक्षाएं बहुत उपयोगी लगीं, लेकिन मुझे पता है कि मैं कार्यात्मक शैली के साथ भी खेल रहा हूं, जिसका उपयोग आउटरेज्ड कार्यक्षमता को जोड़ने के लिए एक हेल्पर्स बनाने के लिए किया जा सकता है जो कि रिएजेज दायरे से बाहर है।
जुराज

बस इस पर अमल किया। जिस तरह से आपने इसे एक वर्ग बनाया है, और इसे निर्यात किया है वह बहुत सुंदर है।
गैविनबल्सन

10

एक ही स्थिति: कई कोणीय परियोजनाओं को पूरा करने और रिएक्ट में जाने के बाद, डीआई के माध्यम से सेवाएं प्रदान करने का एक सरल तरीका नहीं है, एक लापता टुकड़ा (एक तरफ सेवा के विवरण) की तरह लगता है।

संदर्भ और ES7 सज्जाकारों का उपयोग करके हम करीब आ सकते हैं:

https://jaysoo.ca/2015/06/09/react-contexts-and-dependency-injection/

लगता है कि इन लोगों ने इसे एक अलग दिशा में एक कदम और आगे ले लिया है:

http://blog.wolksoftware.com/dependency-injection-in-react-powered-inversifyjs

अभी भी अनाज के खिलाफ काम करने जैसा लगता है। प्रमुख प्रतिक्रिया परियोजना शुरू करने के बाद 6 महीने के समय में इस उत्तर को फिर से जारी करेगा।

संपादित करें: 6 महीने बाद कुछ और प्रतिक्रिया अनुभव के साथ। तर्क की प्रकृति पर विचार करें:

  1. क्या यह केवल (UI) से बंधा हुआ है? इसे एक घटक (स्वीकृत उत्तर) में ले जाएँ।
  2. क्या यह केवल (केवल) राज्य प्रबंधन से जुड़ा हुआ है? इसे एक थंक में स्थानांतरित करें
  3. दोनों से बंधे? अलग फ़ाइल में ले जाएँ, घटक के माध्यम से उपभोग करें चयनकर्ता के और फेंकता ।

कुछ पुन: उपयोग के लिए HOCs के लिए भी पहुँचते हैं लेकिन मेरे लिए उपरोक्त सभी उपयोग मामलों को शामिल किया गया है। इसके अलावा, चिंताओं को अलग रखने और राज्य UI- केंद्रित करने के लिए बतख का उपयोग करके राज्य प्रबंधन को स्केल करने पर विचार करें ।


Imho मुझे लगता है कि ES6 मॉड्यूल प्रणाली का उपयोग करके DI को सेवाएं प्रदान करने का एक सरल तरीका है
मिकी पुरी

1
@ मिक्कीपुरी, ES6 मॉड्यूल DI में कोणीय डीआई का पदानुक्रमित स्वरूप शामिल नहीं होगा, अर्थात। माता-पिता (डोम में) बच्चे के घटकों को आपूर्ति की गई सेवाओं को त्वरित और ओवरराइड करना। Imho ES6 मॉड्यूल DI की तुलना डीएन घटक पदानुक्रम के आधार पर करने के बजाए, निनोजे और स्ट्रक्चरमैप जैसे बैड डि सिस्टम के करीब होने की तुलना करता है। लेकिन मैं इस पर आपके विचार सुनना चाहूंगा।
कोरोला

6

मैं एंगुलर से हूं और रिएक्ट की कोशिश कर रहा हूं, अब तक, उच्च-आदेश आदि का उपयोग करने के लिए एक अनुशंसित (?) तरीका लगता है :

उच्च-क्रम घटक (HOC) घटक तर्क का पुन: उपयोग करने के लिए प्रतिक्रिया में एक उन्नत तकनीक है। HOC प्रति रिएक्ट API का हिस्सा नहीं हैं। वे एक पैटर्न हैं जो कि रिएक्ट की संरचनात्मक प्रकृति से निकलते हैं।

चलो कहते हैं कि तुम है inputऔर textareaऔर एक ही मान्यता तर्क लागू करना चाहते:

const Input = (props) => (
  <input type="text"
    style={props.style}
    onChange={props.onChange} />
)
const TextArea = (props) => (
  <textarea rows="3"
    style={props.style}
    onChange={props.onChange} >
  </textarea>
)

फिर एक HOC लिखें जो लिपटे हुए घटक को मान्य और शैलीबद्ध करता है:

function withValidator(WrappedComponent) {
  return class extends React.Component {
    constructor(props) {
      super(props)

      this.validateAndStyle = this.validateAndStyle.bind(this)
      this.state = {
        style: {}
      }
    }

    validateAndStyle(e) {
      const value = e.target.value
      const valid = value && value.length > 3 // shared logic here
      const style = valid ? {} : { border: '2px solid red' }
      console.log(value, valid)
      this.setState({
        style: style
      })
    }

    render() {
      return <WrappedComponent
        onChange={this.validateAndStyle}
        style={this.state.style}
        {...this.props} />
    }
  }
}

अब वे HOC समान सत्यापन वाला व्यवहार साझा करते हैं:

const InputWithValidator = withValidator(Input)
const TextAreaWithValidator = withValidator(TextArea)

render((
  <div>
    <InputWithValidator />
    <TextAreaWithValidator />
  </div>
), document.getElementById('root'));

मैंने एक साधारण डेमो बनाया ।

संपादित करें : एक और डेमो फ़ंक्शंस का एक सरणी पास करने के लिए प्रॉप्स का उपयोग कर रहा है ताकि आप कई मान्य कार्यों द्वारा रचित तर्क साझा कर सकें HOCजैसे:

<InputWithValidator validators={[validator1,validator2]} />
<TextAreaWithValidator validators={[validator1,validator2]} />

Edit2 : React 16.8+ एक नया फीचर प्रदान करता है, हुक , तर्क साझा करने का एक और अच्छा तरीका।

const Input = (props) => {
  const inputValidation = useInputValidation()

  return (
    <input type="text"
    {...inputValidation} />
  )
}

function useInputValidation() {
  const [value, setValue] = useState('')
  const [style, setStyle] = useState({})

  function handleChange(e) {
    const value = e.target.value
    setValue(value)
    const valid = value && value.length > 3 // shared logic here
    const style = valid ? {} : { border: '2px solid red' }
    console.log(value, valid)
    setStyle(style)
  }

  return {
    value,
    style,
    onChange: handleChange
  }
}

https://stackblitz.com/edit/react-shared-validation-logic-using-hook?file=index.js


धन्यवाद। मैं वास्तव में इस समाधान से सीखा है। क्या होगा अगर मुझे एक से अधिक सत्यापनकर्ता होने की आवश्यकता है उदाहरण के लिए 3 अक्षरों के सत्यापनकर्ता के अलावा, क्या होगा यदि मैं एक और सत्यापनकर्ता रखना चाहता हूं जो यह सुनिश्चित करता है कि कोई संख्या दर्ज नहीं की गई है। क्या हम सत्यापनकर्ताओं की रचना कर सकते हैं?
यूसुफ शेरिफ

1
@ YoussefSherif आप कई सत्यापन कार्य तैयार कर सकते हैं और उन्हें सहारा के रूप में पास कर सकते HOCहैं, दूसरे डेमो के लिए मेरा संपादन देखें।
बॉब

तो HOC मूल रूप से कंटेनर घटक है?
सेंसेई

हां, रिएक्ट डॉक से: "ध्यान दें कि एक एचओसी इनपुट घटक को संशोधित नहीं करता है, और न ही अपने व्यवहार को कॉपी करने के लिए वंशानुक्रम का उपयोग करता है। बल्कि, एक एचओसी एक कंटेनर घटक में लपेटकर मूल घटक की रचना करता है। एक एचओसी एक शुद्ध है। शून्य साइड-इफेक्ट्स के साथ कार्य करें। "
बॉब

1
आवश्यकता तर्क को इंजेक्ट करने की थी, मैं यह नहीं देखता कि हमें ऐसा करने के लिए एचओसी की आवश्यकता क्यों है। जब आप इसे एचओसी के साथ कर सकते हैं, तो यह अधिक जटिल लगता है। HOCs के बारे में मेरी समझ तब है जब कुछ अतिरिक्त राज्य भी हैं जिन्हें जोड़ने और प्रबंधित करने की आवश्यकता है, न कि शुद्ध तर्क (जो यहाँ मामला था)।
मिकी पुरी

4

सेवा में भी कोणीय तक सीमित नहीं है, Angular2 + ,

सेवा केवल सहायक कार्यों का संग्रह है ...

और उन्हें बनाने और अनुप्रयोग में पुन: उपयोग करने के कई तरीके हैं ...

1) वे सभी अलग-अलग फ़ंक्शन हो सकते हैं जो जेएस फ़ाइल से निर्यात किए जाते हैं, नीचे के समान:

export const firstFunction = () => {
   return "firstFunction";
}

export const secondFunction = () => {
   return "secondFunction";
}
//etc

2) हम फैक्ट्री पद्धति का भी उपयोग कर सकते हैं, जैसे कार्यों का संग्रह ... ईएस 6 के साथ यह एक फ़ंक्शन निर्माता के बजाय एक वर्ग हो सकता है:

class myService {

  constructor() {
    this._data = null;
  }

  setMyService(data) {
    this._data = data;
  }

  getMyService() {
    return this._data;
  }

}

इस मामले में आपको नई कुंजी के साथ एक उदाहरण बनाने की आवश्यकता है ...

const myServiceInstance = new myService();

इस मामले में भी, प्रत्येक उदाहरण का अपना जीवन है, इसलिए सावधान रहें यदि आप इसे साझा करना चाहते हैं, तो उस स्थिति में आपको केवल इच्छित उदाहरण निर्यात करना चाहिए ...

3) यदि आपका कार्य और बर्तन साझा नहीं होने जा रहे हैं, तो आप उन्हें रिएक्ट घटक में भी डाल सकते हैं, इस मामले में, बस आपकी प्रतिक्रिया घटक में कार्य के रूप में ...

class Greeting extends React.Component {
  getName() {
    return "Alireza Dezfoolian";
  }

  render() {
    return <h1>Hello, {this.getName()}</h1>;
  }
}

4) एक और तरीका जिससे आप चीजों को संभाल सकते हैं, Redux का उपयोग कर सकते हैं , यह आपके लिए एक अस्थायी स्टोर है, इसलिए यदि आपके पास यह आपके रिएक्ट एप्लिकेशन में है , तो यह आपको कई गटर सेटर कार्यों में मदद कर सकता है आपके द्वारा उपयोग किए ... यह एक बड़े स्टोर की तरह है जो आपके राज्यों का ट्रैक रखते हैं और इसे आपके घटकों में साझा कर सकते हैं, इसलिए हम सेवाओं में उपयोग होने वाले गेट्टर सेटर के सामान के लिए कई दर्द से छुटकारा पा सकते हैं ...

DRY कोड को करना हमेशा अच्छा होता है और कोड को पुन: प्रयोज्य और पठनीय बनाने के लिए जो उपयोग करने की आवश्यकता होती है उसे दोहराते नहीं हैं, लेकिन React ऐप में कोणीय तरीकों का पालन करने की कोशिश न करें , जैसा कि आइटम 4 में उल्लेख किया गया है, Redux का उपयोग करने से आपकी आवश्यकता कम हो सकती है सेवाओं और आप उन्हें आइटम 1 जैसे कुछ पुन: प्रयोज्य सहायक कार्यों के लिए उपयोग करने की सीमा ...


ज़रूर, आप इसे मेरी निजी वेबसाइट पर देख सकते हैं, जो मेरे प्रोफाइल पेज से लिंक है ...
अलिर्ज़ा

"न रिएक्ट में एंगुलर तरीके का पालन करें" .. अहम एंगुलर रेडक्स का उपयोग करने को बढ़ावा देता है और आरएक्सजेएस / स्टोर जैसे ऑब्जर्वबल्स और रेडक्स जैसे राज्य प्रबंधन का उपयोग करके स्टोर को प्रेजेंटेशनल घटकों को स्ट्रीम करता है। .. क्या आपका मतलब AngularJS था? Cuz कि एक और बात है
Spock

1

मैं भी तुम्हारी तरह एक ही बूट में हूं। आपके द्वारा उल्लेख किए गए मामले में, मैं एक इनपुट घटक के रूप में इनपुट सत्यापन यूआई घटक को लागू करूंगा।

मैं मानता हूं कि सत्यापन तर्क को लागू करना चाहिए (चाहिए) युग्मित नहीं होना चाहिए। इसलिए मैं इसे एक अलग जेएस मॉड्यूल में डालूंगा।

यही है, तर्क के लिए जो युग्मित नहीं होना चाहिए जेएस मॉड्यूल / वर्ग को अलग फ़ाइल में उपयोग करें, और "सेवा" से घटक को डी-जोड़ी करने के लिए आवश्यकता / आयात का उपयोग करें।

यह दोनों स्वतंत्र रूप से निर्भरता इंजेक्शन और यूनिट परीक्षण के लिए अनुमति देता है।


1

या आप प्रतिक्रिया घटक में वर्ग विरासत "http" इंजेक्षन कर सकते हैं

वस्तु के माध्यम से।

  1. अपडेट करें :

    ReactDOM.render(<ReactApp data={app} />, document.getElementById('root'));
  2. बस इस तरह रिएक्ट कंपोनेंट रिएक्टएप संपादित करें:

    class ReactApp extends React.Component {
    
    state = {
    
        data: ''
    
    }
    
        render(){
    
        return (
            <div>
            {this.props.data.getData()}      
            </div>
    
        )
        }
    }

0

अच्छी तरह से पुन: प्रयोज्य तर्क के लिए सबसे अधिक उपयोग किया जाने वाला पैटर्न या तो एक हुक लिख रहा है या एक बर्तन फाइल बना रहा है। यह इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं।

hooks/useForm.js

जैसे अगर आप फॉर्म डेटा को वेरिफाई करना चाहते हैं तो मैं useForm.js नाम से एक कस्टम हुक बनाऊंगा और इसे डेटा फॉर्म प्रदान करूंगा और बदले में यह मुझे दो चीजों से युक्त एक वस्तु लौटाएगा:

Object: {
    value,
    error,
}

जैसे ही आप प्रगति करते हैं आप निश्चित रूप से इससे अधिक चीजें वापस कर सकते हैं।

utils/URL.js

एक अन्य उदाहरण यह होगा कि आप किसी URL से कुछ जानकारी निकालना चाहते हैं, तो मैं इसके लिए एक बर्तन फ़ाइल बनाऊँगा जिसमें एक फंक्शन होगा और जहाँ आवश्यक हो वहाँ आयात करें:

 export function getURLParam(p) {
...
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.