प्रतिक्रिया में घटकों के बीच कार्यों को साझा करने का सही तरीका


92

मेरे पास कई घटक हैं जो सभी को एक ही काम करने की आवश्यकता है। (एक सरल कार्य जो अपने बच्चे के घटकों पर मैप करता है और प्रत्येक को कुछ करता है)। फिलहाल मैं प्रत्येक घटक में इस विधि को परिभाषित कर रहा हूं। लेकिन मैं केवल एक बार इसे परिभाषित करना चाहता हूं।

मैं इसे शीर्ष स्तर के घटक में परिभाषित कर सकता हूं और फिर इसे एक प्रस्ताव के रूप में पास कर सकता हूं। लेकिन यह बिल्कुल सही नहीं लगता है। यह एक प्रोपे से ज्यादा लाइब्रेरी फंक्शन है। (मुझे लगता है)।

ऐसा करने का सही तरीका क्या है?


की जाँच करें इस लिंक । या google में "mixins" और "HOC" की खोज करें।
बोरज़

जवाबों:


38

आप की तरह कुछ का उपयोग करते हैं browserify तो आप एक बाहरी फ़ाइल यानी util.js कि निर्यात कुछ उपयोगिता कार्यों हो सकता है।

var doSomething = function(num) {
 return num + 1;
}

exports.doSomething = doSomething;

फिर आवश्यकता के अनुसार इसकी आवश्यकता होती है

var doSomething = require('./util.js').doSomething;

@AnkitSinghaniya जो निर्भर करता है, आप अपने ऐप के फ्रंट एंड स्टेट को प्रबंधित करने के लिए क्या उपयोग कर रहे हैं?
डेवॉक

1
मैं प्रतिक्रिया राज्यों का उपयोग कर रहा हूं।
अक्स

मैं क्यों कर रहा हूँ 'doSomething' को परिभाषित नहीं किया गया है, क्या कोई विचार नहीं है?
अभिजीत चक्र 14

48

नवीनतम जावास्क्रिप्ट ES6 सिंटैक्स के साथ Utils.js

Utils.jsकई कार्यों, आदि के साथ इस तरह फ़ाइल बनाएँ

const someCommonValues = ['common', 'values'];

export const doSomethingWithInput = (theInput) => {
   //Do something with the input
   return theInput;
};

export const justAnAlert = () => {
   alert('hello');
};

फिर अपने घटकों में जिन्हें आप उपयोग फ़ंक्शंस का उपयोग करना चाहते हैं, उन विशिष्ट फ़ंक्शंस का आयात करें जिनकी आवश्यकता है। आपको सब कुछ आयात करने की आवश्यकता नहीं है

import {doSomethingWithInput, justAnAlert} from './path/to/utils.js/file'

और फिर घटक के भीतर इन कार्यों का उपयोग इस तरह से करें:

justAnAlert();
<p>{doSomethingWithInput('hello')}</p>

1
/fileआयात लाइन के अंत में क्या है ?
एलेक्स

@alex यह केवल एक उदाहरण है। उपयोग के लिए अपने रिश्तेदार पथ रखो। वहाँ पर
Fangming

14

यदि आप सहायक कार्यों में राज्य से छेड़छाड़ करना चाहते हैं, तो इसका अनुसरण करें:

  1. एक Help.js फ़ाइल बनाएँ:

    export function myFunc(){ return this.state.name; //define it according to your needs }

  2. आपकी घटक फ़ाइल में सहायक सहायक फ़ंक्शन आयात करें:

    import {myFunc} from 'path-to/Helpers.js'

  3. अपने कंस्ट्रक्टर में उस सहायक फ़ंक्शन को कक्षा में जोड़ें

    constructor(){ this.myFunc = myFunc.bind(this) }

  4. अपने रेंडर फ़ंक्शन में इसका उपयोग करें:

    render(){ <div>{this.myFunc()}</div> }


10

यहां कुछ उदाहरण दिए गए हैं कि आप FetchUtil.handleErrorएक रिएक्शन घटक ( App) में फ़ंक्शन ( ) का पुन: उपयोग कैसे कर सकते हैं ।

समाधान 1: CommonJS मॉड्यूल सिंटैक्स का उपयोग करना

module.exports = {
  handleError: function(response) {
    if (!response.ok) throw new Error(response.statusText);
    return response;
  },
};

समाधान 2: "createClass" का उपयोग करना (प्रतिक्रिया v16)

util / FetchUtil.js

const createReactClass = require('create-react-class');

const FetchUtil = createReactClass({
  statics: {
    handleError: function(response) {
      if (!response.ok) throw new Error(response.statusText);
      return response;
    },
  },
  render() {
  },
});

export default FetchUtil;

नोट: यदि आप प्रतिक्रिया v15.4 (या नीचे) का उपयोग कर रहे हैं, तो आपको createClassनिम्नानुसार आयात करने की आवश्यकता है:

import React from 'react';
const FetchUtil = React.createClass({});

स्रोत: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

घटक (FetchUtil का पुन: उपयोग करता है)

घटकों / App.jsx

import Categories from './Categories.jsx';
import FetchUtil from '../utils/FetchUtil';
import Grid from 'material-ui/Grid';
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {categories: []};
  }

  componentWillMount() {
    window
      .fetch('/rest/service/v1/categories')
      .then(FetchUtil.handleError)
      .then(response => response.json())
      .then(categories => this.setState({...this.state, categories}));
  }

  render() {
    return (
      <Grid container={true} spacing={16}>
        <Grid item={true} xs={12}>
          <Categories categories={this.state.categories} />
        </Grid>
      </Grid>
    );
  }
}

export default App;

7

उपयोग फ़ाइल बनाने के अलावा एक अन्य ठोस विकल्प एक withComponentMapper()आवरण बनाने के लिए एक उच्च क्रम घटक का उपयोग करना होगा । यह घटक एक पैरामीटर के रूप में एक घटक में ले जाएगा और इसे वापस लौटा देगा componentMapper()फ़ंक्शन के साथ एक प्रोप के रूप में पारित हो गया।

रिएक्ट में यह एक अच्छा अभ्यास माना जाता है। आप यह जान सकते हैं कि यहाँ विस्तार से कैसे किया जा सकता है।


मैं इस बात से उत्सुक हूं कि रिएक्ट कंपोनेंट इनहेरिटेंस को क्यों हतोत्साहित करता है जहां विराम पैटर्न समान लगता है?
वर्कवाइज

@ उत्तराधिकार का उपयोग करने के दो घटक हैं
जेक

4

एक उपयोगिता फ़ंक्शन की तरह लगता है, उस स्थिति में इसे एक अलग स्थिर उपयोगिता मॉड्यूल में क्यों नहीं रखा जाता है?

अन्यथा यदि आप बाबेल जैसे ट्रांसपिलर का उपयोग कर रहे हैं, तो आप es7 के स्थैतिक तरीकों का उपयोग कर सकते हैं:

class MyComponent extends React.Component {
  static someMethod() { ...

या फिर यदि आप React.createClass का उपयोग कर रहे हैं, तो आप स्टैटिक्स ऑब्जेक्ट का उपयोग कर सकते हैं :

var MyComponent = React.createClass({
  statics: {
    customMethod: function(foo) {
      return foo === 'bar';
    }
  }

हालाँकि मैं उन विकल्पों की सलाह नहीं देता, लेकिन उपयोगिता विधि के लिए एक घटक को शामिल करने का कोई मतलब नहीं है।

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

अन्य विकल्प वर्ग का विस्तार करने के लिए एक मिश्रण का उपयोग करना है, लेकिन मैं आपको सलाह नहीं देता हूं कि जैसा कि आप इसे es6 + में नहीं कर सकते (और मुझे इस मामले में लाभ नहीं दिखता है)।


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

1
नोट: React.createClass15.5.0 प्रतिक्रिया के बाद से पदावनत किया गया है। create-react-app के create-react-classबजाय npm मॉड्यूल का उपयोग करने का सुझाव देता है ।
एलेक्स जॉन्सन

मैं ओपी के रूप में एक ही काम करने के लिए देख रहा हूँ, लेकिन मैं यहाँ थोड़ा उलझन में हूँ। आप अपने द्वारा सूचीबद्ध किसी भी विकल्प की अनुशंसा नहीं करते हैं। आप क्या सलाह देते हैं?
कुकिला

मैं बस फ़ंक्शन के लिए एक फ़ाइल बनाऊंगा जैसे doSomething.js, या कई समान "उपयोगिता" कार्यों के साथ एक फ़ाइल उदा। utils.jsऔर उन कार्यों को आयात करें जहां आपको उनका उपयोग करने की आवश्यकता है
डोमिनिक

4

मैं नीचे दो शैलियों को दिखाऊंगा, और आप यह चुनना चाहते हैं कि घटकों का तर्क एक-दूसरे से कितना संबंधित है।

स्टाइल 1 - अपेक्षाकृत संबंधित घटकों को कॉलबैक संदर्भों के साथ बनाया जा सकता है , जैसे ./components/App.js...

<SomeItem
    ref={(instance) => {this.childA = instance}}
/>

<SomeOtherItem
    ref={(instance) => {this.childB = instance}}
/>

और फिर आप उनके बीच इस तरह साझा कार्यों का उपयोग कर सकते हैं ...

this.childA.investigateComponent(this.childB);  // call childA function with childB as arg
this.childB.makeNotesOnComponent(this.childA);  // call childB function with childA as arg

स्टाइल 2 - बर्तन-प्रकार के घटकों को इस तरह बनाया जा सकता है , ./utils/time.js...

export const getTimeDifference = function (start, end) {
    // return difference between start and end
}

और फिर उन्हें इस तरह से इस्तेमाल किया जा सकता है , ./components/App.js...

import React from 'react';
import {getTimeDifference} from './utils/time.js';

export default class App extends React.Component {
    someFunction() {
        console.log(getTimeDifference("19:00:00", "20:00:00"));
    }
}

किसका उपयोग करें?

यदि तर्क अपेक्षाकृत संबंधित है (वे केवल एक ही ऐप में एक साथ उपयोग किए जाते हैं), तो आपको घटकों के बीच राज्यों को साझा करना चाहिए। लेकिन अगर आपका तर्क दूर से संबंधित है (जैसे, गणित का उपयोग, पाठ-स्वरूपण उपयोग), तो आपको उपयोग करना चाहिए और उपयोग करना चाहिए कक्षा के कार्य।


2

क्या आपको इसके लिए मिक्सी का उपयोग नहीं करना चाहिए? Https://facebook.github.io/react/docs/reusable-compords.html देखें

हालांकि वे एहसान से बाहर हो रहे हैं। https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-compenders-94a0d2f9e750

उपयोगी हो सकता है


मैं मानता हूं कि मिक्सिन एक सामान्य फ़ंक्शन का निर्यात करने की तुलना में यहां एक बेहतर समाधान है।
ताओ हुआंग

@ ताओहुआंग कुछ बातों पर विचार करने के लिए, 1. मिक्सिन भविष्य के प्रमाण नहीं हैं और आधुनिक ऐप में कम और कम उपयोग किए जाएंगे, 2. एक निर्यात किए गए फ़ंक्शन का उपयोग करना आपके कोड फ्रेमवर्क को अज्ञेय बनाता है - आप आसानी से किसी अन्य js प्रोजेक्ट पर उन फ़ंक्शन का उपयोग कर सकते हैं। मिक्सी का उपयोग न करने के बारे में इस पोस्ट को भी पढ़ें -> facebook.github.io/react/blog/2016/07/13/…
deowk

एक मिक्सिन राज्य तक पहुंच सकता है और संशोधित कर सकता है, जबकि एक विशेषता नहीं है, और जब से ओपी कह रहा है कि वे एक फ़ंक्शन लाइब्रेरी के रूप में व्यवहार करना चाहते हैं, तो एक मिक्सिन सही समाधान नहीं होगा।
होल्डऑफहंगर

इसे अपडेट करने के लिए, उच्च क्रम वाले कार्यों का उपयोग करें। facebook.github.io/react/docs/higher-order-compenders.html
डेवेट

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