ফেসবুক প্রতিক্রিয়াতে কোড পুনরায় ব্যবহারের জন্য মিক্সিন বনাম উপাদানগুলি ব্যবহার করা


116

আমি একটি ব্যাকবোন প্রকল্পে ফেসবুক প্রতিক্রিয়া ব্যবহার করতে শুরু করেছি এবং এখনও পর্যন্ত এটি সত্যিই ভাল চলছে।
যাইহোক, আমি লক্ষ্য করেছি যে আমার প্রতিক্রিয়া কোডটিতে কিছু সদৃশ চলছে।

উদাহরণস্বরূপ, আমি বিভিন্ন ফর্ম মত উইজেট আছে মত যুক্তরাষ্ট্রের সঙ্গে INITIAL, SENDINGএবং SENT। যখন একটি বোতাম টিপানো হয়, ফর্মটি যাচাই করা দরকার, একটি অনুরোধ করা হবে এবং তারপরে রাষ্ট্র আপডেট করা হবে। রাজ্য this.stateঅবশ্যই ক্ষেত্রের মান সহ প্রতিক্রিয়া ভিতরে রাখা হয় ।

এগুলি যদি ব্যাকবোন মতামত হয় FormViewতবে আমি একটি বেস ক্লাস বলেছিলাম তবে আমার ধারণাটি ছিল যে প্রতিক্রিয়াটি ভিউ লজিক ভাগ করে নেওয়ার জন্য সাবক্লাসিং সমর্থন করে না বা সমর্থনও করে না (আমি ভুল হলে আমাকে সংশোধন করি)।

আমি প্রতিক্রিয়াতে কোড পুনঃব্যবহারের দুটি পন্থা দেখেছি:

আমি কি সংশোধন করি যে মিশ্রণ এবং পাত্রে প্রতিক্রিয়াতে উত্তরাধিকারের পক্ষে অগ্রাধিকার দেওয়া হয়? এটা কি ইচ্ছাকৃত ডিজাইনের সিদ্ধান্ত? দ্বিতীয় অনুচ্ছেদে আমার "ফর্ম উইজেট" উদাহরণের জন্য একটি মিশ্রণ বা একটি ধারক উপাদান ব্যবহার করা আরও কী অর্থপূর্ণ হবে?

তাদের বর্তমান অবস্থার সাথে FeedbackWidgetএবং এখানে একটি বক্তব্য রয়েছেJoinWidget । তাদের অনুরূপ কাঠামো, অনুরূপ beginSendপদ্ধতি রয়েছে এবং উভয়েরই কিছু বৈধতা সমর্থন (এখনও সেখানে নেই) প্রয়োজন হবে।


এটির আপডেট হিসাবে - প্রতিক্রিয়ায় দীর্ঘ ভবিষ্যতে মিক্সিনগুলিকে সমর্থন করার বিষয়ে দ্বিতীয় চিন্তাভাবনা রয়েছে, কারণ যখন আপনার উদাহরণস্বরূপ ডাইডমাউন্টগুলি কেবল যাদুবিদ্যায় কাজ করছে তখন কিছু জটিল জিনিস করছে যাতে তারা একে অপরকে অতিরিক্ত লেখায় না .. কারণ মিশ্রণগুলি খুব সরল এবং উদ্দেশ্য জন্য উপযুক্ত নয়
ডমিনিক

প্রতিক্রিয়াটির সাথে আমার তেমন অভিজ্ঞতা নেই তবে আপনি আপনার নিজের মিশ্রণটি এমন ফাংশনগুলির সাথে সংজ্ঞায়িত করতে পারেন যা প্রকৃত প্রতিক্রিয়া অবজেক্টগুলির নেমস্পেসের সাথে ওভারল্যাপ করে না। তারপরে আপনার সাধারণ প্রতিক্রিয়া উপাদান ফাংশনগুলি থেকে কেবল "সুপারক্লাস" / কম্পোজিশন অবজেক্ট ফাংশনগুলি কল করুন। তারপরে প্রতিক্রিয়া ফাংশন এবং উত্তরাধিকার সূত্রে প্রাপ্ত ফাংশনগুলির মধ্যে কোনও ওভারল্যাপ নেই। এটি কিছু বয়লারপ্লেট হ্রাস করতে সহায়তা করে, তবে ঘটতে থাকা যাদুটিকে সীমাবদ্ধ করে এবং পর্দার আড়ালে নিজেকে পরিচালনা করতে এটিকে সহজ করে তোলে। এটা কি সত্যিই গর্ভধারণ করা শক্ত? আমি আশা করি আমি নিজেকে পরিষ্কার করে দিয়েছি।
আলেকজান্ডার মিলস 21

মিক্সিনগুলি কখনই মারা যায় না কারণ আপনি সর্বদা কেবল ডিআইওয়াই মিক্সিন তৈরি করতে পারেন। প্রতিক্রিয়া কেবল মিক্সিনগুলির জন্য "দেশীয়" সমর্থন করবে না তবে আপনি এখনও দেশীয় জেএসের সাথে নিজেকে মিশ্রিত করতে পারেন।
আলেকজান্ডার মিলস 21

উত্তর:


109

আপডেট: এই উত্তরটি পুরানো। পারলে মিশিন থেকে দূরে থাকুন। আমি তোমাকে সতর্ক করেছিলাম!
মিক্সিনস মারা গেছে। দীর্ঘ লাইভ কম্পোজিশন

প্রথমে, আমি এর জন্য সাব-কম্পোনেন্ট ব্যবহার করার চেষ্টা করেছি এবং FormWidgetএবং InputWidget। যাইহোক, আমি এই পদ্ধতিটি অর্ধেক করেই ছেড়ে দিয়েছি কারণ আমি উত্পন্ন ব্যক্তি inputএবং তাদের রাজ্যের উপর আরও ভাল নিয়ন্ত্রণ চেয়েছিলাম ।

দুটি নিবন্ধ যা আমাকে সবচেয়ে বেশি সাহায্য করেছে:

এটি প্রমাণিত হয়েছে যে আমার কেবল দুটি (বিভিন্ন) মিশ্রণ লিখতে হবে: ValidationMixinএবং FormMixin
আমি তাদের কীভাবে আলাদা করেছি তা এখানে।

ValidationMixin

বৈধকরণ মিশ্রণটি আপনার রাজ্যের কয়েকটি বৈশিষ্ট্যে আপনার বৈধকরণকারীর ক্রিয়াকলাপ চালানোর জন্য সুবিধার পদ্ধতিগুলি যুক্ত করে এবং অ্যারেতে "ত্রুটিযুক্ত" বৈশিষ্ট্যগুলি সংরক্ষণ করে state.errorsযাতে আপনি সংশ্লিষ্ট ক্ষেত্রগুলি হাইলাইট করতে পারেন।

উত্স ( সংক্ষেপে )

define(function () {

  'use strict';

  var _ = require('underscore');

  var ValidationMixin = {
    getInitialState: function () {
      return {
        errors: []
      };
    },

    componentWillMount: function () {
      this.assertValidatorsDefined();
    },

    assertValidatorsDefined: function () {
      if (!this.validators) {
        throw new Error('ValidatorMixin requires this.validators to be defined on the component.');
      }

      _.each(_.keys(this.validators), function (key) {
        var validator = this.validators[key];

        if (!_.has(this.state, key)) {
          throw new Error('Key "' + key + '" is defined in this.validators but not present in initial state.');
        }

        if (!_.isFunction(validator)) {
          throw new Error('Validator for key "' + key + '" is not a function.');
        }
      }, this);
    },

    hasError: function (key) {
      return _.contains(this.state.errors, key);
    },

    resetError: function (key) {
      this.setState({
        'errors': _.without(this.state.errors, key)
      });
    },

    validate: function () {
      var errors = _.filter(_.keys(this.validators), function (key) {
        var validator = this.validators[key],
            value = this.state[key];

        return !validator(value);
      }, this);

      this.setState({
        'errors': errors
      });

      return _.isEmpty(errors);
    }
  };

  return ValidationMixin;

});

ব্যবহার

ValidationMixinতিনটি পদ্ধতির আছে: validate, hasErrorএবং resetError
এটি শ্রেণীর validatorsঅবজেক্টের সংজ্ঞা দেবে বলে প্রত্যাশা করে propTypes:

var JoinWidget = React.createClass({
  mixins: [React.addons.LinkedStateMixin, ValidationMixin, FormMixin],

  validators: {
    email: Misc.isValidEmail,
    name: function (name) {
      return name.length > 0;
    }
  },

  // ...

});

যখন ব্যবহারকারী সাবমিশন বোতাম টিপেন, আমি কল করি validate। একটি কল validateপ্রতিটি যাচাইকারী চালানো হবে এবং this.state.errorsবৈধতা যাচাইয়ের ব্যর্থ বৈশিষ্ট্যের কী রয়েছে এমন একটি অ্যারের সাথে পপুলেট করা হবে ।

আমার renderপদ্ধতিতে, আমি hasErrorক্ষেত্রগুলির জন্য সঠিক CSS ক্লাস উত্পন্ন করতে ব্যবহার করি । যখন ব্যবহারকারী ক্ষেত্রের মধ্যে ফোকাস রাখে, আমি resetErrorপরের validateকল পর্যন্ত ত্রুটি হাইলাইট অপসারণ করতে কল করি।

renderInput: function (key, options) {
  var classSet = {
    'Form-control': true,
    'Form-control--error': this.hasError(key)
  };

  return (
    <input key={key}
           type={options.type}
           placeholder={options.placeholder}
           className={React.addons.classSet(classSet)}
           valueLink={this.linkState(key)}
           onFocus={_.partial(this.resetError, key)} />
  );
}

FormMixin

ফর্ম মিশ্রণ ফর্ম রাজ্য পরিচালনা করে (সম্পাদনযোগ্য, জমা দেওয়া, জমা দেওয়া)। অনুরোধ প্রেরণের সময় আপনি ইনপুট এবং বোতাম অক্ষম করতে এবং এটি প্রেরিত হওয়ার সাথে সাথে নিজের দৃষ্টিভঙ্গি আপডেট করার জন্য এটি ব্যবহার করতে পারেন।

উত্স ( সংক্ষেপে )

define(function () {

  'use strict';

  var _ = require('underscore');

  var EDITABLE_STATE = 'editable',
      SUBMITTING_STATE = 'submitting',
      SUBMITTED_STATE = 'submitted';

  var FormMixin = {
    getInitialState: function () {
      return {
        formState: EDITABLE_STATE
      };
    },

    componentDidMount: function () {
      if (!_.isFunction(this.sendRequest)) {
        throw new Error('To use FormMixin, you must implement sendRequest.');
      }
    },

    getFormState: function () {
      return this.state.formState;
    },

    setFormState: function (formState) {
      this.setState({
        formState: formState
      });
    },

    getFormError: function () {
      return this.state.formError;
    },

    setFormError: function (formError) {
      this.setState({
        formError: formError
      });
    },

    isFormEditable: function () {
      return this.getFormState() === EDITABLE_STATE;
    },

    isFormSubmitting: function () {
      return this.getFormState() === SUBMITTING_STATE;
    },

    isFormSubmitted: function () {
      return this.getFormState() === SUBMITTED_STATE;
    },

    submitForm: function () {
      if (!this.isFormEditable()) {
        throw new Error('Form can only be submitted when in editable state.');
      }

      this.setFormState(SUBMITTING_STATE);
      this.setFormError(undefined);

      this.sendRequest()
        .bind(this)
        .then(function () {
          this.setFormState(SUBMITTED_STATE);
        })
        .catch(function (err) {
          this.setFormState(EDITABLE_STATE);
          this.setFormError(err);
        })
        .done();
    }
  };

  return FormMixin;

});

ব্যবহার

এটি উপাদানটির একটি পদ্ধতি সরবরাহ করার প্রত্যাশা করে sendRequest:, যা একটি ব্লুবার্ড প্রতিশ্রুতি ফিরিয়ে দেয়। (এটি কিউ বা অন্যান্য প্রতিশ্রুতি গ্রন্থাগারের সাথে কাজ করার জন্য এটি সংশোধন করা তুচ্ছ ial

এটি সুবিধাজনক পদ্ধতি যেমন isFormEditable, isFormSubmittingএবং সরবরাহ করে isFormSubmitted। এছাড়া অনুরোধ বন্ধ লাথি একটি পদ্ধতি প্রদান করে: submitForm। আপনি ফর্ম বোতামের onClickহ্যান্ডলার থেকে কল করতে পারেন ।


2
@ জেমসেজুয়েলা আসলে আমি পরে আরও বেশি উপাদান-ইশ পদ্ধতির দিকে চলে এসেছি (এখনও প্রচুর পরিমাণে মিক্সিন ব্যবহার করছি), আমি এটিকে কিছুটা হলেও প্রসারিত করতে পারি ..
ড্যান আব্রামভ ২

1
"আরও উপাদান-ইশ পদ্ধতির" সম্পর্কে কিছু সংবাদ আছে?
নীল কলর

3
@ নীল কলার এখনও নয়, আমি এতে সন্তুষ্ট নই। :-) বর্তমানে আমি FormInputএটির মাধ্যমে তার মালিকের সাথে কথা বলছি formLinkformLinkমত valueLink, এবং FormMixinএর linkValidatedState(name, validator)পদ্ধতি থেকে ফিরে আসে । FormInputএর কাছ থেকে এর মান পেয়ে যায় formLink.valueএবং কল করে formLink.requestBlurএবং এতে formLink.requestFocusবৈধতা দেয় FormMixin। অবশেষে, ইনপুটটির জন্য ব্যবহৃত প্রকৃত উপাদানটি কাস্টমাইজ করার জন্য, আমি এটি এখানে পাঠাতে পারি FormInput:<FormInput component={React.DOM.textarea} ... />
ড্যান আব্রামভ

সুন্দর উত্তর - কিছু টিপস: আপনাকে doneব্লুবার্ডে কল করতে হবে না এবং কোডটি Q (বা দেশীয় প্রতিশ্রুতি) এর মতো কাজ করবে - অবশ্যই ব্লুবার্ড আরও ভাল। এছাড়াও লক্ষ করুন যে উত্তরটি থেকেই সিনট্যাক্সটি প্রতিক্রিয়াতে পরিবর্তিত হয়েছিল।
বেনিয়ামিন গ্রুইনবাউম

4

আমি প্রতিক্রিয়া দিয়ে একটি এসপিএ তৈরি করছি (1 বছর থেকে উত্পাদনে), এবং আমি প্রায় কখনও মিক্সিন ব্যবহার করি না।

মিক্সিনগুলির জন্য আমার কাছে বর্তমানে কেবলমাত্র ইউসकेসটি হ'ল আপনি যখন এমন আচরণ ভাগ করতে চান যা প্রতিক্রিয়াটির জীবনচক্রের পদ্ধতিগুলি ( componentDidMountইত্যাদি) ব্যবহার করে। ড্যান আব্রামভ তার লিঙ্কে (বা ES6 শ্রেণীর উত্তরাধিকার ব্যবহার করে) যে উচ্চ-আদেশের উপাদানগুলি দ্বারা কথা বলার মাধ্যমে এই সমস্যাটি সমাধান হয়েছে ।

প্রতিক্রিয়াটির "লুকানো" প্রসঙ্গ বৈশিষ্ট্যটি ব্যবহার করে ফ্রেমওয়ার্ক এপিআই সমস্ত উপাদানগুলিতে উপলব্ধ করার জন্য মিক্সিনগুলি প্রায়শই ফ্রেমওয়ার্কগুলিতে ব্যবহৃত হয় । ES6 শ্রেণীর উত্তরাধিকারের সাথে এটি আর দরকার হবে না।


বেশিরভাগ সময়ে, মিক্সিনগুলি ব্যবহৃত হয়, তবে সত্যই এটি প্রয়োজন হয় না এবং সহজ সহায়কগুলির সাথে ইজিলার প্রতিস্থাপন করা যেতে পারে।

উদাহরণ স্বরূপ:

var WithLink = React.createClass({
  mixins: [React.addons.LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

আপনি খুব সহজেই LinkedStateMixinকোডটি রিফ্যাক্টর করতে পারেন যাতে সিনট্যাক্সটি হতে পারে:

var WithLink = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={LinkState(this,'message')} />;
  }
});

কোন বড় পার্থক্য আছে?


আপনি সঠিক. আসলে লিঙ্কডস্টেটমিক্সিন ডক্সগুলি মিক্সিন ছাড়া এটি কীভাবে করবেন তা স্পੈਲ করে। এই নির্দিষ্ট মিশ্রণটি সত্যিই কেবলমাত্র একটি সামান্য সিনট্যাকটিক চিনি।
পরেরজনটেক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.