রেডাক্সে অ্যাসিঙ্ক প্রবাহের জন্য আমাদের মিডলওয়্যারের দরকার কেন?


685

ডক্স অনুসারে, "মিডলওয়্যার ব্যতীত, রেডাক্স স্টোর কেবলমাত্র সিঙ্ক্রোনাস ডেটা প্রবাহকে সমর্থন করে" । আমি কেন বুঝতে পারছি না এই ঘটনাটি কেন? কেন ধারক উপাদান অ্যাসিঙ্ক এপিআই এবং তারপরে dispatchক্রিয়াকলাপগুলি কল করতে পারে না ?

উদাহরণস্বরূপ, একটি সাধারণ ইউআই কল্পনা করুন: একটি ক্ষেত্র এবং একটি বোতাম। যখন ব্যবহারকারী বোতামটি চাপায়, ক্ষেত্রটি দূরবর্তী সার্ভারের ডেটা দিয়ে পপুলেটে যায়।

একটি ক্ষেত্র এবং একটি বোতাম

import * as React from 'react';
import * as Redux from 'redux';
import { Provider, connect } from 'react-redux';

const ActionTypes = {
    STARTED_UPDATING: 'STARTED_UPDATING',
    UPDATED: 'UPDATED'
};

class AsyncApi {
    static getFieldValue() {
        const promise = new Promise((resolve) => {
            setTimeout(() => {
                resolve(Math.floor(Math.random() * 100));
            }, 1000);
        });
        return promise;
    }
}

class App extends React.Component {
    render() {
        return (
            <div>
                <input value={this.props.field}/>
                <button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>
                {this.props.isWaiting && <div>Waiting...</div>}
            </div>
        );
    }
}
App.propTypes = {
    dispatch: React.PropTypes.func,
    field: React.PropTypes.any,
    isWaiting: React.PropTypes.bool
};

const reducer = (state = { field: 'No data', isWaiting: false }, action) => {
    switch (action.type) {
        case ActionTypes.STARTED_UPDATING:
            return { ...state, isWaiting: true };
        case ActionTypes.UPDATED:
            return { ...state, isWaiting: false, field: action.payload };
        default:
            return state;
    }
};
const store = Redux.createStore(reducer);
const ConnectedApp = connect(
    (state) => {
        return { ...state };
    },
    (dispatch) => {
        return {
            update: () => {
                dispatch({
                    type: ActionTypes.STARTED_UPDATING
                });
                AsyncApi.getFieldValue()
                    .then(result => dispatch({
                        type: ActionTypes.UPDATED,
                        payload: result
                    }));
            }
        };
    })(App);
export default class extends React.Component {
    render() {
        return <Provider store={store}><ConnectedApp/></Provider>;
    }
}

যখন রফতানি করা উপাদানটি রেন্ডার করা হয়, তখন আমি বোতামটি ক্লিক করতে পারি এবং ইনপুটটি সঠিকভাবে আপডেট হয়।

কলটিতে updateফাংশনটি নোট করুন connect। এটি এমন একটি ক্রিয়া প্রেরণ করে যা অ্যাপটিকে জানায় যে এটি আপডেট হচ্ছে এবং তারপরে একটি অ্যাসিঙ্ক কল করে। কল শেষ হওয়ার পরে, সরবরাহ করা মান অন্য ক্রিয়াকলাপের পেডলোড হিসাবে প্রেরণ করা হয়।

এই পদ্ধতির সাথে কী ভুল? ডকুমেন্টেশনের পরামর্শ অনুসারে আমি কেন রেডাক্স থাঙ্ক বা রেডাক্স প্রতিশ্রুতি ব্যবহার করতে চাই?

সম্পাদনা: আমি ক্লুগুলির জন্য রেডাক্স রেপোটি অনুসন্ধান করেছিলাম এবং দেখেছিলাম যে অ্যাকশন ক্রিয়েটরদের অতীতে খাঁটি ফাংশন হওয়া দরকার। উদাহরণস্বরূপ, এখানে একজন ব্যবহারকারী আসিঙ্ক ডেটা প্রবাহের জন্য আরও ভাল ব্যাখ্যা প্রদানের চেষ্টা করছেন:

অ্যাকশন স্রষ্টা নিজেই এখনও একটি খাঁটি ফাংশন, তবে এটি যে থঙ্ক ফাংশনটি দেয় তা হওয়ার দরকার নেই এবং এটি আমাদের অ্যাসিঙ্ক কলগুলি করতে পারে

অ্যাকশন নির্মাতাদের আর খাঁটি হওয়ার দরকার নেই। সুতরাং, থঙ্ক / প্রতিশ্রুতি মিডলওয়্যারগুলি অবশ্যই আগে প্রয়োজন ছিল, তবে মনে হচ্ছে এটি এখন আর নেই?


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

1
পরীক্ষামূলকতার জন্য @ ড্যানআব্রামভ এটি তবে ভাল অনুশীলনকারী হতে পারে। রেডাক্স-সাগা এটির
সেবাস্তিয়ান লরবার

উত্তর:


701

এই পদ্ধতির সাথে কী ভুল? ডকুমেন্টেশনের পরামর্শ অনুসারে আমি কেন রেডাক্স থাঙ্ক বা রেডাক্স প্রতিশ্রুতি ব্যবহার করতে চাই?

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

আপনি পড়তে পারেন আরও বিশদ ওয়াকথ্রোয়ের জন্য "একটি টাইমআউট সহ একটি রেডাক্স অ্যাকশন কীভাবে প্রেরণ করবেন" এ আমার উত্তরটি

রেডাক্স থাঙ্ক বা রেডাক্স প্রতিশ্রুতির মতো মিডলওয়্যার আপনাকে কেবল থানস বা প্রতিশ্রুতি প্রেরণের জন্য "সিনট্যাক্স চিনির" সরবরাহ করে তবে আপনি তা করেন না এটি ব্যবহার করতে হবে না।

সুতরাং, কোনও মিডলওয়্যার ছাড়াই আপনার অ্যাকশন স্রষ্টা দেখতে দেখতে দেখতে পারেন

// action creator
function loadData(dispatch, userId) { // needs to dispatch, so it is first argument
  return fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_DATA_FAILURE', err })
    );
}

// component
componentWillMount() {
  loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
}

তবে থঙ্ক মিডলওয়্যারের সাহায্যে আপনি এটিকে এভাবে লিখতে পারেন:

// action creator
function loadData(userId) {
  return dispatch => fetch(`http://data.com/${userId}`) // Redux Thunk handles these
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_DATA_FAILURE', err })
    );
}

// component
componentWillMount() {
  this.props.dispatch(loadData(this.props.userId)); // dispatch like you usually do
}

সুতরাং কোন বিশাল পার্থক্য আছে। পরের পদ্ধতির সম্পর্কে আমি একটি জিনিস পছন্দ করি তা হল উপাদানটি যত্ন করে না যে অ্যাকশন স্রষ্টা অ্যাসিঙ্ক is এটি কেবলমাত্র dispatchসাধারণভাবে কল করে , এটি mapDispatchToPropsযেমন অ্যাকশন নির্মাতাকে একটি সংক্ষিপ্ত বাক্য গঠন সহ বাঁধতেও ব্যবহার করতে পারে ইত্যাদি উপাদানগুলি জানেন না কীভাবে ক্রিয়া স্রষ্টাগুলি প্রয়োগ করা হয় এবং আপনি বিভিন্ন অ্যাসিঙ্ক পদ্ধতির মধ্যে পরিবর্তন করতে পারেন (রেডাক্স থাঙ্ক, রেডাক্স প্রতিশ্রুতি, রেডাক্স সাগা ) উপাদান পরিবর্তন না করে। অন্যদিকে, সাবেক, স্পষ্ট পদ্ধতির সঙ্গে, আপনার উপাদান জানি ঠিক করে একটি নির্দিষ্ট কল ASYNC, এবং প্রয়োজন dispatchকিছু কনভেনশন দ্বারা পাশ করা (ক সিঙ্ক প্যারামিটার হিসাবে, উদাহরণস্বরূপ)।

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

প্রথম পদ্ধতির সাথে আমাদের কী ধরণের ক্রিয়া স্রষ্টাকে কল করছি সে সম্পর্কে আমাদের সচেতন হওয়া দরকার:

// action creators
function loadSomeData(dispatch, userId) {
  return fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_SOME_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_SOME_DATA_FAILURE', err })
    );
}
function loadOtherData(dispatch, userId) {
  return fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_OTHER_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_OTHER_DATA_FAILURE', err })
    );
}
function loadAllData(dispatch, userId) {
  return Promise.all(
    loadSomeData(dispatch, userId), // pass dispatch first: it's async
    loadOtherData(dispatch, userId) // pass dispatch first: it's async
  );
}


// component
componentWillMount() {
  loadAllData(this.props.dispatch, this.props.userId); // pass dispatch first
}

রেডাক্স থাঙ্ক অ্যাকশন স্রষ্টাদের dispatchসাথে অন্যান্য অ্যাকশন স্রষ্টাদের ফলাফল হতে পারে এবং সেগুলি সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস কিনা তা ভেবেও ভাবতে পারে না:

// action creators
function loadSomeData(userId) {
  return dispatch => fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_SOME_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_SOME_DATA_FAILURE', err })
    );
}
function loadOtherData(userId) {
  return dispatch => fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'LOAD_OTHER_DATA_SUCCESS', data }),
      err => dispatch({ type: 'LOAD_OTHER_DATA_FAILURE', err })
    );
}
function loadAllData(userId) {
  return dispatch => Promise.all(
    dispatch(loadSomeData(userId)), // just dispatch normally!
    dispatch(loadOtherData(userId)) // just dispatch normally!
  );
}


// component
componentWillMount() {
  this.props.dispatch(loadAllData(this.props.userId)); // just dispatch normally!
}

এই পদ্ধতির সাথে, যদি আপনি পরে আপনার অ্যাকশন স্রষ্টাদের বর্তমান রেডাক্স অবস্থার সন্ধান করতে চান তবে আপনি getStateকলিং কোডটি কোনও পরিবর্তন না করেই থিংসকে দেওয়া দ্বিতীয় যুক্তিটি ব্যবহার করতে পারেন :

function loadSomeData(userId) {
  // Thanks to Redux Thunk I can use getState() here without changing callers
  return (dispatch, getState) => {
    if (getState().data[userId].isLoaded) {
      return Promise.resolve();
    }

    fetch(`http://data.com/${userId}`)
      .then(res => res.json())
      .then(
        data => dispatch({ type: 'LOAD_SOME_DATA_SUCCESS', data }),
        err => dispatch({ type: 'LOAD_SOME_DATA_FAILURE', err })
      );
  }
}

আপনার যদি এটি সিঙ্ক্রোনাস হওয়ার দরকার হয় তবে আপনি কোনও কলিং কোড পরিবর্তন না করে এটিও করতে পারেন:

// I can change it to be a regular action creator without touching callers
function loadSomeData(userId) {
  return {
    type: 'LOAD_SOME_DATA_SUCCESS',
    data: localStorage.getItem('my-data')
  }
}

সুতরাং মিডিয়াওয়্যার যেমন রেডাক্স থাঙ্ক বা রেডাক্স প্রতিশ্রুতি ব্যবহার করার সুবিধাটি হ'ল উপাদানগুলি ক্রিয়াকলাপকারীরা কীভাবে প্রয়োগ করা হয় সে সম্পর্কে সচেতন নয় এবং তারা রেডাক্স রাজ্যের বিষয়ে যত্নশীল কিনা, তারা সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস, এবং তারা অন্য ক্রিয়াকলাপকারীদের কল করে কিনা । নেতিবাচক দিকটি সামান্য কিছুটা দিকনির্দেশনা, তবে আমরা বিশ্বাস করি এটি বাস্তব অ্যাপ্লিকেশনগুলিতে এটি মূল্যবান।

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

আমি ক্লুগুলির জন্য রেডাক্স রেপোটি অনুসন্ধান করেছিলাম এবং সন্ধান পেয়েছি যে অ্যাকশন ক্রিয়েটরদের অতীতে খাঁটি ফাংশন হওয়া দরকার।

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


57
ড্যানের চিন্তাভাবনাটি বলার জন্য সংক্ষিপ্ত উপায়টি হ'ল: মিডলওয়্যারটি কেন্দ্রিয়ায়িত পন্থা, এই পদ্ধতিতে আপনি আপনার উপাদানগুলি সরল এবং সাধারণীকরণ করতে পারবেন এবং ডেটা প্রবাহকে এক জায়গায় নিয়ন্ত্রণ করতে পারবেন। যদি আপনি বড় অ্যাপ্লিকেশন বজায় রাখেন তবে আপনি এটি উপভোগ করবেন =)
সের্গেই ল্যাপিন

3
@ আসডফাসডফ্যাডস আমি দেখতে পাচ্ছি না কেন এটি কাজ করবে না। এটি ঠিক একই কাজ করবে; করা alertপর dispatch()কর্ম ing।
ড্যান আব্রামভ

9
আপনার প্রথম কোড উদাহরণে উপান্ত্য লাইন: loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch। আমাকে প্রেরণে কেন পাস করতে হবে? যদি কনভেনশন দ্বারা যদি কেবলমাত্র একটি একক বিশ্বব্যাপী স্টোর থাকে তবে আমি কেন কেবল সেই রেফারেন্সটি করি না কেন store.dispatchযখনই আমার প্রয়োজন হয়, যেমন, প্রয়োজন loadData?
সেরেন দেবোইস

10
@ সেরেনডেবোইস আপনার অ্যাপ্লিকেশনটি যদি ক্লায়েন্টের পক্ষে থাকে তবে কেবল এটিই কাজ করবে। যদি এটি সার্ভারে রেন্ডার হয় তবে আপনি storeপ্রতিটি অনুরোধের জন্য আলাদা উদাহরণ রাখতে চাইবেন যাতে আপনি এটির আগেই সংজ্ঞা দিতে পারবেন না।
ড্যান আব্রামভ

3
কেবল উল্লেখ করতে চাই যে এই উত্তরে ১৩৯ টি লাইন রয়েছে যা রেডেক্স
গায়

447

আপনি না।

তবে ... আপনার রিডেক্স-সাগা ব্যবহার করা উচিত :)

ড্যান আব্রামভের উত্তরটি সঠিক, redux-thunkতবে আমি রেডুএক্স-সাগা সম্পর্কে আরও কিছু কথা বলব যা বেশ অনুরূপ তবে আরও শক্তিশালী।

অত্যাবশ্যক ভিএস ঘোষণা

  • ডোম : jQuery হ'ল অপরিহার্য / প্রতিক্রিয়া ঘোষণামূলক
  • মনডস : আইও অপরিহার্য / নিখরচায় ঘোষণাযোগ্য
  • রেডাক্স এফেক্টস : redux-thunkআবশ্যকীয় / redux-sagaএটি ঘোষণামূলক

যখন আপনার হাতে আইও মোনাড বা প্রতিশ্রুতির মতো কোনও কান্ড রয়েছে তখন আপনি সহজেই বুঝতে পারবেন না যে একবার কার্যকর করার পরে এটি কী করবে। থাঙ্ককে পরীক্ষা করার একমাত্র উপায় হ'ল এটি চালানো, এবং প্রেরককে (বা পুরো বাইরের বিশ্বের যদি এটি আরও স্টাফের সাথে ইন্টারঅ্যাক্ট করে ...) উপহাস করে।

আপনি যদি মক ব্যবহার করছেন তবে আপনি কার্যকরী প্রোগ্রামিং করছেন না।

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

সূত্র

সাগাগুলি (যেমন তারা বাস্তবায়িত হয়েছিল redux-saga) ঘোষণামূলক এবং ফ্রি মোনাড বা প্রতিক্রিয়া উপাদানগুলির মতো, তারা কোনও মক ছাড়াই পরীক্ষা করা আরও সহজ।

এই নিবন্ধটি দেখুন :

আধুনিক এফপিতে, আমাদের প্রোগ্রামগুলি লেখা উচিত নয় - আমাদের প্রোগ্রামগুলির বিবরণ লেখা উচিত, যা আমরা তখন আত্মবিশ্বাস, রূপান্তর এবং ইচ্ছায় ব্যাখ্যা করতে পারি।

(আসলে, রেডাক্স-সাগা একটি হাইব্রিডের মতো: প্রবাহটি অপরিহার্য তবে এর প্রভাবগুলি ঘোষণামূলক)

বিভ্রান্তি: ক্রিয়া / ইভেন্ট / আদেশগুলি ...

সিকিউআরএস / ইভেন্টসোর্সিং এবং ফ্লাক্স / রেডাক্সের মতো কিছু ব্যাকএন্ড ধারণাগুলি কীভাবে সম্পর্কিত হতে পারে তা নিয়ে সীমান্ত বিশ্বে প্রচুর বিভ্রান্তি রয়েছে, কারণ ফ্লাক্সে আমরা "ক্রিয়া" শব্দটি ব্যবহার করি যা কখনও কখনও আবশ্যক কোড ( LOAD_USER) এবং ইভেন্ট উভয়কেই উপস্থাপন করতে পারে ( USER_LOADED)। আমি বিশ্বাস করি যে ইভেন্ট-সোর্সিংয়ের মতো আপনার কেবল ইভেন্ট প্রেরণ করা উচিত।

অনুশীলনে সাগা ব্যবহার করা

কোনও ব্যবহারকারী প্রোফাইলের লিঙ্ক সহ একটি অ্যাপ্লিকেশনটি কল্পনা করুন। প্রতিটি মিডলওয়্যারের সাথে এটি হ্যান্ডেল করার মূর্তিমান পদ্ধতিটি হ'ল:

redux-thunk

<div onClick={e => dispatch(actions.loadUserProfile(123)}>Robert</div>

function loadUserProfile(userId) {
  return dispatch => fetch(`http://data.com/${userId}`)
    .then(res => res.json())
    .then(
      data => dispatch({ type: 'USER_PROFILE_LOADED', data }),
      err => dispatch({ type: 'USER_PROFILE_LOAD_FAILED', err })
    );
}

redux-saga

<div onClick={e => dispatch({ type: 'USER_NAME_CLICKED', payload: 123 })}>Robert</div>


function* loadUserProfileOnNameClick() {
  yield* takeLatest("USER_NAME_CLICKED", fetchUser);
}

function* fetchUser(action) {
  try {
    const userProfile = yield fetch(`http://data.com/${action.payload.userId }`)
    yield put({ type: 'USER_PROFILE_LOADED', userProfile })
  } 
  catch(err) {
    yield put({ type: 'USER_PROFILE_LOAD_FAILED', err })
  }
}

এই কাহিনী অনুবাদ করে:

প্রতিবার ব্যবহারকারীর নাম ক্লিক হয়ে গেলে ব্যবহারকারী প্রোফাইলটি আনুন এবং তারপরে লোড হওয়া প্রোফাইলের সাথে একটি ইভেন্ট প্রেরণ করুন।

আপনি দেখতে পাচ্ছেন, এর কিছু সুবিধা রয়েছে redux-saga

পারফরম্যান্সের ব্যবহারটি takeLatestপ্রকাশ করার জন্য যে আপনি কেবলমাত্র শেষ ব্যবহারকারী নামটির ডেটা পেতে আগ্রহী (ব্যবহারকারীর প্রচুর ব্যবহারকারীর উপর খুব দ্রুত ক্লিক করা হলে একযোগে সমস্যাগুলি হ্যান্ডেল করুন)। এই ধরণের জিনিস থাঙ্কস সহ শক্ত। আপনি takeEveryযদি এই আচরণটি না চান তবে আপনি ব্যবহার করতে পারতেন ।

আপনি ক্রিয়া নির্মাতাদের শুদ্ধ রাখুন। নোট করুন এটি অ্যাকশনক্রিটারগুলি রাখার জন্য এখনও কার্যকর (সাগা putএবং উপাদানগুলিতে dispatch), কারণ এটি আপনাকে ভবিষ্যতে ক্রিয়া বৈধতা ( দৃ /়তা / প্রবাহ / টাইপস্ক্রিপ্ট) যুক্ত করতে সহায়তা করতে পারে।

আপনার কোডটি অনেক বেশি পরীক্ষামূলক হয়ে উঠেছে কারণ প্রভাবগুলি ঘোষিত হয়

আরপিসি-মতো কলগুলির মতো ট্রিগার করার জন্য আপনার আর দরকার নেই actions.loadUser()। আপনার ইউআইকে কেবল কী ঘটেছে তা প্রেরণ করতে হবে। আমরা কেবল ইভেন্টগুলিতে আগুন জ্বালিয়েছি (সর্বদা অতীতে থাকি !) আর ক্রিয়া করি না। এর অর্থ হ'ল আপনি ডিকোপলড "হাঁস" বা বাউন্ডেড কনটেক্সট তৈরি করতে পারেন এবং সাগা এই মডুলার উপাদানগুলির মধ্যে সংযোগের স্থান হিসাবে কাজ করতে পারে।

এর অর্থ হ'ল আপনার মতামতগুলি পরিচালনা করা আরও সহজ কারণ কারণ কী ঘটেছে এবং ফলস্বরূপ কী হওয়া উচিত তার মধ্যে সেই অনুবাদ স্তরটি ধারণ করার জন্য তাদের আর দরকার নেই don't

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

কিছু তর্ক করতে পারে যে জেনারেটরগুলি স্থানীয় ভেরিয়েবলগুলির সাথে রিডেক্স স্টোরের বাইরে রাষ্ট্রীয়ভাবে লুকিয়ে রাখতে পারে, তবে আপনি যদি টাইমার ইত্যাদি শুরু করে থাঙ্কসের ভিতরে জটিল জিনিসগুলি অর্কেস্টেট করতে শুরু করেন তবে যাইহোক আপনার একই সমস্যা হতে পারে। এবং এমন একটি selectপ্রভাব রয়েছে যা এখন আপনার রেডাক্স স্টোর থেকে কিছু রাজ্য পাওয়ার অনুমতি দেয়।

সাগাস সময়-ভ্রমণ হতে পারে এবং জটিল ফ্লো লগিং এবং ডি-সরঞ্জামগুলি সক্ষম করে যা বর্তমানে কাজ করা হচ্ছে। এখানে ইতিমধ্যে কার্যকর করা কিছু সাধারণ অ্যাসিঙ্ক ফ্লো লগিং রয়েছে:

সাগা ফ্লো লগিং

Decoupling

সাগস কেবলমাত্র রেডুক্স থঙ্কগুলি প্রতিস্থাপন করছে না। এগুলি ব্যাকএন্ড / বিতরণ সিস্টেম / ইভেন্ট-সোর্সিং থেকে আসে।

এটি একটি খুব সাধারণ ভ্রান্ত ধারণা যে সাগাসগুলি এখানে আপনার রিডেক্স থঙ্ককে আরও ভাল টেস্টিবিলিটির সাথে প্রতিস্থাপন করতে এসেছে। আসলে এটি হ'ল রিডেক্স-সাগা সম্পর্কিত একটি বাস্তবায়ন বিশদ। পরীক্ষামূলকতার জন্য থ্যাঙ্কসের চেয়ে ঘোষণামূলক প্রভাবগুলি ব্যবহার করা ভাল, তবে সাগা প্যাটার্নটি আবশ্যকীয় বা ঘোষণামূলক কোডের শীর্ষে প্রয়োগ করা যেতে পারে।

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

সীমানা বিশ্বে এটি সহজ করার জন্য, এখানে উইজেট 1 এবং উইজেট 2 রয়েছে বলে ধারণা করুন। যখন উইজেট 1 এ কিছু বোতাম ক্লিক করা হয়, তারপরে উইজেট 2 এ এর ​​প্রভাব থাকতে হবে। 2 টি উইজেট একসাথে সংযুক্ত করার পরিবর্তে (যেমন উইজেট 1 এমন কোনও ক্রিয়া প্রেরণ করে যা উইজেট 2 কে লক্ষ্য করে), উইজেট 1 কেবলমাত্র তার বোতামটি ক্লিক করে প্রেরণ করে। তারপরে সাগা এই বোতামটির জন্য ক্লিক করুন এবং তারপরে উইজেট 2 সচেতন এমন একটি নতুন ইভেন্ট প্রেরণ করে উইজেট 2 আপডেট করুন।

এটি ইন্ডিয়ারেশনের একটি স্তর যুক্ত করে যা সাধারণ অ্যাপ্লিকেশনগুলির জন্য অপ্রয়োজনীয় তবে জটিল অ্যাপ্লিকেশনগুলিকে স্কেল করা আরও সহজ করে তোলে। আপনি এখন উইজেট 1 এবং উইজেট 2 বিভিন্ন এনএমপি সংগ্রহস্থলে প্রকাশ করতে পারেন যাতে তাদের ক্রিয়াকলাপের একটি রেজিস্ট্রি ভাগ করে না নিয়ে তাদের একে অপরের সম্পর্কে কখনও জানতে হবে না। 2 টি উইজেট এখন সীমাবদ্ধ প্রসঙ্গ যা পৃথকভাবে বেঁচে থাকতে পারে। সামঞ্জস্যপূর্ণ হওয়ার জন্য তাদের একে অপরের দরকার নেই এবং অন্যান্য অ্যাপ্লিকেশনগুলিতেও এটি পুনরায় ব্যবহার করা যেতে পারে। সাগা হ'ল দুটি উইজেটের মধ্যে সংযোগ স্থাপন যা আপনার ব্যবসায়ের জন্য অর্থবহ উপায়ে তাদেরকে সমন্বয় করে।

আপনার রেডাক্স অ্যাপ্লিকেশনটি কীভাবে গঠন করবেন সে সম্পর্কে কয়েকটি দুর্দান্ত নিবন্ধ, যার উপর ভিত্তি করে আপনি ডিকপলিং কারণে রেডাক্স-সাগা ব্যবহার করতে পারেন:

একটি কংক্রিট ইউজকেস: বিজ্ঞপ্তি সিস্টেম

আমি চাই আমার উপাদানগুলি অ্যাপ্লিকেশন বিজ্ঞপ্তিগুলির প্রদর্শনটি ট্রিগার করতে সক্ষম হোক। তবে আমি চাই না যে আমার উপাদানগুলি নোটিফিকেশন সিস্টেমের সাথে একত্রে মিলিত হোক যার নিজস্ব ব্যবসায়িক বিধি রয়েছে (একই সাথে প্রদর্শিত হবে সর্বোচ্চ 3 টি বিজ্ঞপ্তি, বিজ্ঞপ্তি সারিবদ্ধ, 4 সেকেন্ডের প্রদর্শন-সময় ইত্যাদি ...)।

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

বিজ্ঞপ্তিগুলি

আমি এখানে বর্ণনা করেছি যে কীভাবে সাগা দিয়ে এটি করা যায়

একে সাগা বলা হয় কেন?

সাগা শব্দটি ব্যাকএন্ড ওয়ার্ল্ড থেকে এসেছে। আমি প্রথম দিকে দীর্ঘ আলোচনায় ইয়াসিনকে (রেডাক্স-সাগা রচয়িতা) পরিচয় করিয়েছিলাম ।

প্রথমদিকে, এই শব্দটি একটি কাগজ দিয়ে প্রবর্তিত হয়েছিল , বিতর্কিত লেনদেনের ক্ষেত্রে সাগা প্যাটার্নটি চূড়ান্ত ধারাবাহিকতা পরিচালনা করতে ব্যবহার করার কথা ছিল, তবে ব্যাকএন্ড বিকাশকারীরা এর ব্যবহারকে আরও বিস্তৃত সংজ্ঞাতে প্রসারিত করেছেন যাতে এটি এখন "প্রক্রিয়া পরিচালক" হিসাবেও আবৃত হয় প্যাটার্ন (কোনওভাবে আসল সাগা প্যাটার্নটি প্রক্রিয়া পরিচালকের একটি বিশেষ ফর্ম)।

আজ, "সাগা" শব্দটি বিভ্রান্তিকর কারণ এটি 2 টি পৃথক বিষয় বর্ণনা করতে পারে। এটি রিডেক্স-সাগায় ব্যবহৃত হওয়ায় এটি বিতরণকৃত লেনদেনগুলি পরিচালনা করার উপায় নয় বরং আপনার অ্যাপ্লিকেশনটিতে ক্রিয়াকলাপকে সমন্বয় করার উপায় বর্ণনা করে। redux-sagaবলা যেতে পারে redux-process-manager

আরো দেখুন:

বিকল্প

আপনি জেনারেটর ব্যবহারের ধারণা পছন্দ করি না কিন্তু আপনি কাহিনী প্যাটার্ন এবং তার decoupling বৈশিষ্ট্য দ্বারা আগ্রহী, আপনার কাছে সঙ্গে একই অর্জন করতে পারেন redux-পর্যবেক্ষণযোগ্য যা নাম ব্যবহার করে epicসঠিক একই প্যাটার্ন বর্ণনা করতে, কিন্তু সঙ্গে RxJS। আপনি যদি ইতিমধ্যে আরক্সের সাথে পরিচিত হন তবে আপনি ঠিক ঘরে বসে অনুভব করবেন।

const loadUserProfileOnNameClickEpic = action$ =>
  action$.ofType('USER_NAME_CLICKED')
    .switchMap(action =>
      Observable.ajax(`http://data.com/${action.payload.userId}`)
        .map(userProfile => ({
          type: 'USER_PROFILE_LOADED',
          userProfile
        }))
        .catch(err => Observable.of({
          type: 'USER_PROFILE_LOAD_FAILED',
          err
        }))
    );

কিছু রিডেক্স-সাগা দরকারী সংস্থান

2017 পরামর্শ দেয়

  • রেডাক্স-সাগা কেবল এটির প্রয়োজনে ব্যবহার করবেন না। কেবল টেস্টেবল এপিআই কলগুলি মূল্যবান নয়।
  • সর্বাধিক সাধারণ ক্ষেত্রে আপনার প্রকল্প থেকে অংশগুলি অপসারণ করবেন না।
  • yield put(someActionThunk)এটি যদি বোধগম্য হয় তবে কিছুকে থামাতে দ্বিধা করবেন না ।

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

const unsubscribe = store.addDispatchListener(action => {
  if (action.type === 'ping') {
    store.dispatch({ type: 'pong' });
  }
});

64
প্রতিবার যখন আবার ঘুরে দেখি এটি আরও ভাল হচ্ছে getting এটিকে একটি ব্লগ পোস্টে পরিণত করার বিষয়টি বিবেচনা করুন :)।
রেইনারএটস্পিরিট

4
একটি ভাল লেখার জন্য আপনাকে ধন্যবাদ। তবে আমি কিছু বিষয়ে একমত না। LOAD_USER কীভাবে আবশ্যক? আমার কাছে এটি কেবল ঘোষণামূলক নয় - এটি দুর্দান্ত পাঠযোগ্য কোডও দেয়। যেমন উদা। "আমি যখন এই বোতামটি টিপব আমি ADD_ITEM করতে চাই"। আমি কোডটি দেখতে পারি এবং ঠিক কী চলছে তা বুঝতে পারি। যদি এর পরিবর্তে "BUTTON_CLICK" এর প্রভাবকে কিছু বলা হত তবে আমাকে এটি সন্ধান করতে হবে।
মিটলেট

4
চমৎকার উত্তর. এখন অন্য বিকল্প আছে: github.com/blesh/redux-observable
সুইভেনম্যান

4
@ দেরীতে আনওয়ারের জন্য দুঃখিত আপনি যখন প্রেরণ করেন ADD_ITEM, এটি আবশ্যক কারণ আপনি এমন কোনও ক্রিয়া প্রেরণ করেন যা আপনার স্টোরটিতে প্রভাব ফেলতে লক্ষ্য করে: আপনি ক্রিয়াটি কিছু করার প্রত্যাশা করেন। ঘোষিত হ'ল ইভেন্ট-সোর্সিংয়ের দর্শনকে আলিঙ্গন করা: আপনি আপনার অ্যাপ্লিকেশনগুলিতে পরিবর্তনগুলি সক্রিয় করতে কোনও পদক্ষেপ প্রেরণ করবেন না, তবে আপনার অ্যাপ্লিকেশনটিতে কী ঘটেছে তা বর্ণনা করার জন্য আপনি অতীত ঘটনা প্রেরণ করেন। কোনও ইভেন্টের প্রেরণের ক্ষেত্রে অ্যাপ্লিকেশনের অবস্থা পরিবর্তিত হয়েছে তা বিবেচনা করার জন্য যথেষ্ট হওয়া উচিত। একটি রেডাক্স স্টোর রয়েছে যা ইভেন্টে প্রতিক্রিয়া জানায় এটি হ'ল একটি implementation
চ্ছিক

3
আমি এই উত্তরটি পছন্দ করি না কারণ কারওর নিজের লাইব্রেরি বাজারজাত করার জন্য এটি আসল প্রশ্ন থেকে দূরে সরে যায়। এই উত্তরটি দুটি গ্রন্থাগারের তুলনা সরবরাহ করে, যা প্রশ্নের উদ্দেশ্য ছিল না। আসল প্রশ্নটি মিডলওয়্যারটি আদৌ ব্যবহার করবেন কিনা তা জিজ্ঞাসা করছে, যা স্বীকৃত উত্তরের মাধ্যমে ব্যাখ্যা করা হয়েছে।
অভিনব মনছন্দ

31

সংক্ষিপ্ত উত্তর : আমার কাছে অ্যাসিনক্রোনির সমস্যার সম্পূর্ণ যুক্তিযুক্ত পদ্ধতির মতো বলে মনে হচ্ছে। একটি দম্পতি সতর্কতা সঙ্গে।

আমরা সবেমাত্র আমার কাজ শুরু করে একটি নতুন প্রকল্পে কাজ করার সময় আমার খুব অনুরূপ চিন্তাভাবনা ছিল। স্টোরটি আপডেট করার জন্য এবং উপাদানগুলি এমনভাবে উপস্থাপনের জন্য ভ্যানিলা রেডাক্সের মার্জিত সিস্টেমের আমি একটি বড় অনুরাগী ছিলাম যাতে কোনও প্রতিক্রিয়া উপাদান গাছের সাহসিকতা থেকে দূরে থাকে। dispatchঅ্যাসিক্রোনারি পরিচালনা করার জন্য সেই মার্জিত পদ্ধতিটি আঁকানো আমার কাছে অদ্ভুত বলে মনে হয়েছিল ।

আমরা আমাদের লাইব্রেরিতে ফ্যাক্টরড করেছিলাম এমন একটি লাইব্রেরিতে আপনার যা আছে সেখানে সত্যিকারের অনুরূপ দৃষ্টিভঙ্গি দিয়ে আমি শেষ করেছি called রিঅ্যাক্ট-রেডেক্স-কন্ট্রোলার

কয়েকটি কারণে আপনি উপরে যে সঠিক পন্থাটি করেছেন তার সাথে না গিয়ে শেষ করেছিলাম:

  1. আপনি এটি যেভাবে লিখেছেন, সেই প্রেরণকারী ফাংশনগুলির স্টোরটিতে অ্যাক্সেস নেই। আপনার UI উপাদানগুলি প্রেরণকারীর ফাংশনটির প্রয়োজনীয় সমস্ত তথ্যে পাস করার মাধ্যমে আপনি কিছুটা পেতে পারেন। তবে আমি যুক্তি দেব যে এইগুলি এই সমস্ত ইউআই উপাদানগুলি যুক্তিযুক্তভাবে অযৌক্তিকভাবে প্রেরণ করার যুক্তিতে প্রেরণা দেয়। এবং আরও সমস্যাযুক্তভাবে, অ্যাসিঙ্ক ধারাবাহিকতায় আপডেট অবস্থায় অ্যাক্সেসের জন্য প্রেরণ কার্যের কোনও সুস্পষ্ট উপায় নেই।
  2. প্রেরণ ফাংশনগুলিতে dispatchলেক্সিকাল স্কোপের মাধ্যমে নিজেই অ্যাক্সেস থাকে । এই connectবিবৃতিটি হাতছাড়া হয়ে যাওয়ার পরে এটি রিফ্যাক্টরিংয়ের বিকল্পগুলিকে সীমাবদ্ধ করে - এবং এটি কেবলমাত্র একটি updateপদ্ধতির সাথে দেখতে বেশ অনর্থক দেখাচ্ছে । সুতরাং যদি আপনি সেগুলি পৃথক মডিউলগুলিতে বিভক্ত করেন তবে আপনাকে সেই প্রেরণকারী ফাংশনগুলি রচনা করতে দেওয়ার জন্য আপনার কিছু সিস্টেমের প্রয়োজন।

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

  • রিডেক্স-থাঙ্ক এটিকে কার্যকরী উপায়ে করে, আপনার থাঙ্কগুলিতে প্রবেশ করে (গম্বুজের সংজ্ঞা দিয়ে একে একে একে একে ঠিক থাঙ্ক করে না)। আমি অন্যান্য dispatchমিডলওয়্যার পদ্ধতির সাথে কাজ করি নি , তবে আমি ধরে নিই যে তারা মূলত একই রকম।
  • প্রতিক্রিয়া-হ্রাস-নিয়ামক একটি কর্টিনের সাহায্যে এটি করে। বোনাস হিসাবে, এটি আপনাকে "নির্বাচকদের" অ্যাক্সেস দেয়, যা connectকাঁচা, সাধারণীকরণ স্টোরের সাথে সরাসরি কাজ করার পরিবর্তে প্রথম যুক্তি হিসাবে আপনি যে ফাংশনগুলি দিয়েছিলেন তা হতে পারে ।
  • thisবিভিন্ন প্রকার সম্ভাব্য ব্যবস্থার মাধ্যমে আপনি এটিকে প্রসঙ্গে ইনজেকশন দিয়ে বস্তু-কেন্দ্রিক উপায়েও করতে পারেন ।

হালনাগাদ

আমার কাছে এটি ঘটে যে এই কনড্রামের অংশটি প্রতিক্রিয়া-হ্রাসের সীমাবদ্ধতা । connectরাষ্ট্রীয় স্ন্যাপশট পাওয়ার প্রথম যুক্তি , তবে প্রেরণ নয়। দ্বিতীয় যুক্তি প্রেরণ পায় তবে রাষ্ট্র নয়। কোনও ধারাবাহিকতা / কলব্যাকের সময় আপডেট হওয়া রাষ্ট্রটি দেখতে সক্ষম হওয়ার জন্য তাত্পর্যপূর্ণ অবস্থা বর্তমান অবস্থার উপর বন্ধ হয়ে যায় না argument


22

আব্রামভের লক্ষ্য - এবং প্রত্যেকের আদর্শই - কেবল যেখানে সবচেয়ে সর্বাধিক উপযুক্ত সেখানে জটিলতা (এবং অ্যাসিঙ্ক কলগুলি) সজ্জিত করা is

স্ট্যান্ডার্ড রেডাক্স ডেটাফ্লোতে এটি করার সবচেয়ে ভাল জায়গাটি কোথায়? কেমন:

  • হ্রাসকারীদের ? কোনভাবেই না. কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই এগুলি খাঁটি ফাংশন হওয়া উচিত। স্টোর আপডেট করা গুরুতর, জটিল ব্যবসা। এটি দূষিত করবেন না।
  • বোবা দেখার উপাদানগুলি? অবশ্যই না They
  • ধারক উপাদান? সম্ভাব্য তবে উপ-অনুকূল এটি বোঝা যায় যে ধারকটি এমন একটি জায়গা যেখানে আমরা কিছু সম্পর্কিত সম্পর্কিত জটিলতা সজ্জিত করি এবং স্টোরের সাথে ইন্টারঅ্যাক্ট করি তবে:
    • কনটেইনারগুলির বোবা উপাদানগুলির তুলনায় আরও জটিল হওয়া দরকার তবে এটি এখনও একক দায়িত্ব: দর্শন এবং রাষ্ট্র / স্টোরের মধ্যে বাইন্ডিং সরবরাহ করে। আপনার অ্যাসিঙ্ক যুক্তিটি এটি থেকে সম্পূর্ণ আলাদা উদ্বেগ।
    • এটিকে একটি ধারক স্থানে রেখে আপনি একক দর্শন / রুটের জন্য আপনার অ্যাসিঙ্ক যুক্তিকে একটি একক প্রসঙ্গে লক করছেন be খারাপ ধারণা। আদর্শভাবে এটি সমস্ত পুনরায় ব্যবহারযোগ্য এবং পুরোপুরি ডিকপলড।
  • এস ওমে অন্য সার্ভিস মডিউল? খারাপ ধারণা: আপনার স্টোরটিতে অ্যাক্সেস লাগাতে হবে যা একটি রক্ষণাবেক্ষণযোগ্যতা / টেস্টিবিলিটি দুঃস্বপ্ন। রেডাক্সের শস্যের সাথে যাওয়া এবং কেবল সরবরাহিত APIs / মডেলগুলি ব্যবহার করে দোকানে অ্যাক্সেস করা ভাল।
  • ক্রিয়া এবং মিডলওয়্যারগুলি যা তাদের ব্যাখ্যা করে? কেন না?! আরম্ভকারীদের জন্য, আমরা একমাত্র প্রধান বিকল্পটি রেখেছি। :-) আরও যুক্তিযুক্তভাবে, অ্যাকশন সিস্টেমটি নির্ধারণের যুক্তিকে ডিক্লোলড করে যা আপনি যে কোনও জায়গা থেকে ব্যবহার করতে পারেন। এটি স্টোরে অ্যাক্সেস পেয়েছে এবং আরও ক্রিয়া প্রেরণ করতে পারে। এটির একটি একক দায়িত্ব রয়েছে যা অ্যাপ্লিকেশনটির চারপাশে নিয়ন্ত্রণ এবং ডেটা প্রবাহকে সংগঠিত করা এবং বেশিরভাগ অ্যাসিঙ্ক ঠিক সেই সাথে ফিট করে।
    • অ্যাকশন নির্মাতাদের কী? কেন কেবল সেখানে অ্যাসিঙ্ক করবেন না, পরিবর্তে নিজেরাই এবং মিডলওয়্যারগুলিতে?
      • মিডলওয়্যারের মতো প্রথম এবং সর্বাধিক গুরুত্বপূর্ণ, স্রষ্টাদের স্টোরটিতে অ্যাক্সেস নেই। এর অর্থ আপনি নতুন আকস্মিক ক্রিয়াকলাপ প্রেরণ করতে পারবেন না, আপনার অ্যাসিঙ্ক রচনা করতে স্টোর থেকে পড়তে পারবেন না, ইত্যাদি
      • সুতরাং, এমন জায়গায় জটিলতা রাখুন যা প্রয়োজনীয়তার জটিল, এবং সমস্ত কিছু সহজ রাখুন। নির্মাতারা তখন সহজ, তুলনামূলকভাবে খাঁটি ফাংশন হতে পারে যা পরীক্ষা করা সহজ।

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

আমি এই উত্তর ভালবাসি!
মৌরিসিও আভেন্দাসো

13

শুরুতে জিজ্ঞাসিত প্রশ্নের উত্তর দিতে:

কেন ধারক উপাদান অ্যাসিঙ্ক এপিআই কল করতে পারে না এবং তারপরে ক্রিয়াগুলি প্রেরণ করতে পারে?

মনে রাখবেন যে এই দস্তাবেজগুলি Redux এর জন্য, রেডাক্স প্লাস প্রতিক্রিয়া নয়। প্রতিক্রিয়াযুক্ত উপাদানগুলিতে আটকানো রেডাক্স স্টোরগুলি আপনি যা বলছেন ঠিক তেমন করতে পারে, তবে কোনও মিডলওয়্যারবিহীন একটি সরল জেন রেডাক্স স্টোর এতে যুক্তি গ্রহণ করে নাdispatch তবে প্লেইন ওল 'অবজেক্টগুলি ব্যতীত ।

মিডলওয়্যার ছাড়া আপনি অবশ্যই এখনও করতে পারেন

const store = createStore(reducer);
MyAPI.doThing().then(resp => store.dispatch(...));

তবে এটি একটি অনুরূপ ক্ষেত্রে যেখানে অ্যাসিনক্রোনাই রেডাক্স দ্বারা পরিচালিত হওয়ার পরিবর্তে রেডাক্সের চারপাশে মোড়ানো । সুতরাং, মিডলওয়্যারগুলি সরাসরি যা যেতে পারে তা পরিবর্তন করে অ্যাসিক্রোনির অনুমতি দেয় ।dispatch


এটি বলেছিল, আপনার পরামর্শের চেতনাটি আমার কাছে বিশ্বাসযোগ্য valid একটি রেডাক্স + প্রতিক্রিয়া অ্যাপ্লিকেশনটিতে অ্যাসিঙ্ক্রোনিকে পরিচালনা করতে পারে এমন অন্যান্য উপায় অবশ্যই রয়েছে।

মিডলওয়্যার ব্যবহারের একটি সুবিধা হ'ল আপনি ক্রিয়া স্রষ্টাদের ঠিক কীভাবে আটকানো হচ্ছে তা নিয়ে চিন্তা না করেই সাধারণ হিসাবে ব্যবহার করতে পারেন। উদাহরণস্বরূপ, redux-thunkআপনি যে কোডটি লিখেছেন তা ব্যবহারের মতো দেখতে অনেক ভালো লাগে

function updateThing() {
  return dispatch => {
    dispatch({
      type: ActionTypes.STARTED_UPDATING
    });
    AsyncApi.getFieldValue()
      .then(result => dispatch({
        type: ActionTypes.UPDATED,
        payload: result
      }));
  }
}

const ConnectedApp = connect(
  (state) => { ...state },
  { update: updateThing }
)(App);

যা এগুলি সমস্ত কিছুই মূল থেকে পৃথক দেখাচ্ছে না - এটি কেবল কিছুটা বদলে গেছে - এবং connectএটি জানেন নাupdateThing এটি (বা হওয়া দরকার) অ্যাসিনক্রোনাস।

আপনি যদি প্রতিশ্রুতি , পর্যবেক্ষণযোগ্য , সাগা বা ক্রেজি কাস্টম এবং উচ্চ ঘোষণামূলক কর্ম নির্মাতাদের সমর্থন করতে চান, তবে রেডাক্স আপনি যা পাস করেন তা পরিবর্তন করে dispatch(ওরফে, আপনি ক্রিয়া স্রষ্টাদের কাছ থেকে ফিরে যাবেন) তা করতে পারে । connectপ্রয়োজনীয় প্রতিক্রিয়া উপাদানগুলি (বা কল) দিয়ে কোনও শোক না ।


আপনি ক্রিয়া সমাপ্তির জন্য আরও একটি ইভেন্ট প্রেরণের জন্য পরামর্শ দিন advice ক্রিয়া শেষ হওয়ার পরে যখন আপনাকে একটি সতর্কতা () দেখাতে হবে তখন এটি কাজ করবে না। প্রতিক্রিয়া উপাদান ভিতরে প্রতিশ্রুতি যদিও কাজ করে। আমি বর্তমানে প্রতিশ্রুতি পদ্ধতির প্রস্তাব দিই।
ক্যাটালফেটামিন

8

ঠিক আছে, আসুন শুরু করা যাক মিডলওয়্যারগুলি প্রথমে কীভাবে কাজ করছে তা প্রশ্নের উত্তরের উত্তর দেয়, এটিই সোর্স কোডটি রেডাক্সের একটি প্লাইমিডালওয়্যার ফাংশন:

function applyMiddleware() {
  for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
    middlewares[_key] = arguments[_key];
  }

  return function (createStore) {
    return function (reducer, preloadedState, enhancer) {
      var store = createStore(reducer, preloadedState, enhancer);
      var _dispatch = store.dispatch;
      var chain = [];

      var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
      _dispatch = compose.apply(undefined, chain)(store.dispatch);

      return _extends({}, store, {
        dispatch: _dispatch
      });
    };
  };
}

এই অংশটি দেখুন, দেখুন আমাদের প্রেরণ কীভাবে একটি ফাংশনে পরিণত হয়

  ...
  getState: store.getState,
  dispatch: function dispatch(action) {
  return _dispatch(action);
}
  • নোট করুন যে প্রতিটি মিডলওয়্যারকে নাম দেওয়া যুক্তি হিসাবে কাজ dispatchএবং getStateফাংশন দেওয়া হবে ।

ঠিক আছে, রেডাক্সের জন্য সর্বাধিক ব্যবহৃত মিডলওয়্যারগুলির হিসাবে এটি Redux-thunk নিজেকে পরিচয় করিয়ে দেয়:

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

আপনি যেমন দেখেন, এটি কোনও ক্রিয়া পরিবর্তে কোনও ফাংশন ফিরিয়ে দেবে, এর অর্থ আপনি কোনও ফাংশন হিসাবে আপনি যে কোনও সময় অপেক্ষা করতে এবং কল করতে পারবেন ...

তাহলে হেক কি থাবা? এটি উইকিপিডিয়ায় এভাবেই চালু করা হয়েছে:

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

শব্দটির উদ্ভব "চিন্তাভাবনা" এর জোকুলার ডেরাইভেটিভ হিসাবে।

থাঙ্ক হ'ল একটি ফাংশন যা তার মূল্যায়ণকে বিলম্ব করতে কোনও অভিব্যক্তিকে আবৃত করে।

//calculation of 1 + 2 is immediate 
//x === 3 
let x = 1 + 2;

//calculation of 1 + 2 is delayed 
//foo can be called later to perform the calculation 
//foo is a thunk! 
let foo = () => 1 + 2;

সুতরাং দেখুন ধারণাটি কতটা সহজ এবং কীভাবে এটি আপনাকে আপনার অ্যাসিঙ্ক ক্রিয়াগুলি পরিচালনা করতে সহায়তা করে ...

এটি এমন কিছু যা আপনি এগুলি ছাড়া বাঁচতে পারেন তবে প্রোগ্রামিংয়ে মনে রাখবেন সবসময় আরও ভাল, পরিষ্কার ও সঠিক উপায়গুলি করার জন্য ...

মিডলওয়্যার রেডাক্স প্রয়োগ করুন


1
এসও তে প্রথমবার, কিছু পড়েনি। তবে ছবিটি দেখার জন্য কেবল পোস্টটি পছন্দ হয়েছে। আশ্চর্যজনক, ইঙ্গিত, এবং অনুস্মারক।
ভোজেন্দ্র রুনিয়র

2

রেডাক্স-সাগা ব্যবহার করা প্রতিক্রিয়া-রিডাক্স বাস্তবায়নের সেরা মিডলওয়্যার।

যেমন: store.js

  import createSagaMiddleware from 'redux-saga';
  import { createStore, applyMiddleware } from 'redux';
  import allReducer from '../reducer/allReducer';
  import rootSaga from '../saga';

  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(
     allReducer,
     applyMiddleware(sagaMiddleware)
   )

   sagaMiddleware.run(rootSaga);

 export default store;

এবং তারপরে সাগা.জেএস

import {takeLatest,delay} from 'redux-saga';
import {call, put, take, select} from 'redux-saga/effects';
import { push } from 'react-router-redux';
import data from './data.json';

export function* updateLesson(){
   try{
       yield put({type:'INITIAL_DATA',payload:data}) // initial data from json
       yield* takeLatest('UPDATE_DETAIL',updateDetail) // listen to your action.js 
   }
   catch(e){
      console.log("error",e)
     }
  }

export function* updateDetail(action) {
  try{
       //To write store update details
   }  
    catch(e){
       console.log("error",e)
    } 
 }

export default function* rootSaga(){
    yield [
        updateLesson()
       ]
    }

এবং তারপরে action.js

 export default function updateFruit(props,fruit) {
    return (
       {
         type:"UPDATE_DETAIL",
         payload:fruit,
         props:props
       }
     )
  }

এবং তারপরে হ্রাস

import {combineReducers} from 'redux';

const fetchInitialData = (state=[],action) => {
    switch(action.type){
      case "INITIAL_DATA":
          return ({type:action.type, payload:action.payload});
          break;
      }
     return state;
  }
 const updateDetailsData = (state=[],action) => {
    switch(action.type){
      case "INITIAL_DATA":
          return ({type:action.type, payload:action.payload});
          break;
      }
     return state;
  }
const allReducers =combineReducers({
   data:fetchInitialData,
   updateDetailsData
 })
export default allReducers; 

এবং তারপরে main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/components/App.jsx';
import {Provider} from 'react-redux';
import store from './app/store';
import createRoutes from './app/routes';

const initialState = {};
const store = configureStore(initialState, browserHistory);

ReactDOM.render(
       <Provider store={store}>
          <App />  /*is your Component*/
       </Provider>, 
document.getElementById('app'));

এটি চেষ্টা করুন .. কাজ করছে


3
এটি এমন ব্যক্তির পক্ষে গুরুতর উপাদান যা সত্তা বা সত্তার তালিকা ফিরিয়ে দিতে কেবল একটি এপিআই এন্ডপয়েন্টে কল করতে চায়। আপনি সুপারিশ করেন, "কেবল এটি করুন ... তারপরে এটি, তারপরে এই, তারপরে এই অন্য জিনিসটি, তারপরে, এই অন্যান্য জিনিসগুলি, তারপরে চালিয়ে যান, তারপরে .."। তবে মানুষ, এটি ফ্রন্টএন্ড, আমাদের কেবলমাত্র ফ্রন্টএন্ডে ব্যবহারের জন্য ডেটা প্রস্তুত করার জন্য ব্যাকেন্ডে কল করা দরকার। যদি এই পথে যেতে হয় তবে কিছু ভুল, কিছু সত্যিই ভুল এবং কেউ আজকাল KISS প্রয়োগ করছেন না
zameb

হাই, এপিআই কলগুলির জন্য ট্রাই করুন এবং ব্লক ধরুন। একবার API এর প্রতিক্রিয়া জানালে, Reducer ক্রিয়া ধরণের কল করুন।
এস এম চিন্না

1
@ জামেব আপনি ঠিক থাকতে পারেন, তবে আপনার অভিযোগটি নিজেই রেডাক্সের সাথে রয়েছে এবং জটিলতা হ্রাস করার চেষ্টা করার সময় এটি যে সমস্ত শুনানি এনেছে তা।
জুরিস

1

সেখানে সিঙ্ক্রোনাস অ্যাকশন নির্মাতা এবং তারপরে অ্যাসিক্রোনাস অ্যাকশন নির্মাতারা রয়েছেন।

একটি সিঙ্ক্রোনাস অ্যাকশন স্রষ্টা হ'ল এটি আমরা যখন কল করি এটি তত্ক্ষণাত object বস্তুর সাথে সংযুক্ত সমস্ত প্রাসঙ্গিক ডেটা এবং এটি আমাদের হ্রাসকারীদের দ্বারা প্রক্রিয়াজাতকরণের জন্য প্রস্তুত সহ অ্যাকশন অবজেক্টটি ফিরিয়ে দেয়।

অ্যাসিঙ্ক্রোনাস অ্যাকশন নির্মাতারা এমন এক যাতে অবশেষে কোনও ক্রিয়া প্রেরণের জন্য প্রস্তুত হওয়ার আগে কিছুটা সময় প্রয়োজন।

সংজ্ঞা অনুসারে, আপনার কাছে যে কোনও সময় ক্রিয়া স্রষ্টা রয়েছে যা একটি নেটওয়ার্ক অনুরোধ করে, এটি সর্বদা একটি অ্যাসিঙ্ক অ্যাকশন নির্মাতা হিসাবে যোগ্য হতে চলেছে।

আপনি যদি কোনও রেডাক্স অ্যাপ্লিকেশনের অভ্যন্তরে অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের রাখতে চান তবে আপনাকে মিডলওয়্যার নামক কিছু ইনস্টল করতে হবে যা আপনাকে সেই অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের সাথে ডিল করতে দেয়।

আপনি এটি ত্রুটি বার্তায় যাচাই করতে পারেন যা আমাদের async ক্রিয়াকলাপের জন্য কাস্টম মিডলওয়্যার ব্যবহার করতে বলে।

তাহলে মিডলওয়্যার কী এবং রেডাক্সে অ্যাসিঙ্ক প্রবাহের জন্য আমাদের এটির কেন দরকার?

রিডাক্স মিডলওয়্যার যেমন রেডেক্স-থাঙ্কের প্রসঙ্গে, একটি মিডলওয়্যার আমাদের অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের সাথে ডিল করতে সহায়তা করে কারণ এটি এমন একটি জিনিস যা রেডাক্স বাক্সের বাইরে পরিচালনা করতে পারে না।

মিডলওয়্যারটি রেডাক্স চক্রের সাথে সংহত করে, আমরা এখনও অ্যাকশন স্রষ্টাকে কল করছি যা প্রেরণ করা হবে এমন একটি ক্রিয়া ফিরিয়ে আনবে তবে এখন যখন আমরা কোনও ক্রিয়া পাঠাচ্ছি, বরং তা আমাদের সমস্ত হ্রাসকারীদের কাছে সরাসরি পাঠানোর চেয়ে আমরা যাচ্ছি বলার অপেক্ষা রাখে না যে অ্যাপ্লিকেশনের অভ্যন্তরে বিভিন্ন মিডলওয়্যারের মাধ্যমে একটি ক্রিয়া প্রেরণ করা হবে।

একটি একক রেডাক্স অ্যাপ্লিকেশনটির অভ্যন্তরে, আমরা যতগুলি চাই আমাদের বা তার চেয়ে কম মিডলওয়্যার রাখতে পারি। বেশিরভাগ ক্ষেত্রে, আমরা যে প্রকল্পগুলিতে কাজ করি সেগুলিতে আমাদের রেডাক্স স্টোর পর্যন্ত এক বা দুটি মিডলওয়্যার থাকবে।

মিডলওয়্যার হ'ল একটি সরল জাভাস্ক্রিপ্ট ফাংশন যা আমাদের প্রেরিত প্রতিটি কর্মের সাথে ডাকা হবে। সেই ফাংশনের অভ্যন্তরে কোনও মিডলওয়্যারের কোনও ক্রমকে হ্রাসকারীদের কাছে প্রেরণ করা থেকে বিরত রাখার সুযোগ রয়েছে, এটি কোনও ক্রিয়াকে সংশোধন করতে পারে বা কোনও ক্রিয়াকলাপ ঘটাতে পারে আপনার কোনও উপায়ে যা উদাহরণস্বরূপ, আমরা একটি মিডওয়্যার তৈরি করতে পারি যা লগগুলি কনসোল করে দেয় প্রতিটি ক্রিয়া আপনি কেবল আপনার দেখার আনন্দের জন্য প্রেরণ করেন।

ওপেন সোর্স মিডলওয়্যারের একটি প্রচুর সংখ্যা রয়েছে আপনি নিজের প্রকল্পের উপর নির্ভরতা হিসাবে ইনস্টল করতে পারেন can

আপনি কেবল ওপেন সোর্স মিডলওয়্যার ব্যবহার করা বা নির্ভরতা হিসাবে এগুলি ইনস্টল করার মধ্যে সীমাবদ্ধ নন। আপনি নিজের কাস্টম মিডলওয়্যার লিখতে পারেন এবং এটি আপনার রেডাক্স স্টোরের অভ্যন্তরে ব্যবহার করতে পারেন।

মিডলওয়্যারের অন্যতম জনপ্রিয় ব্যবহার (এবং আপনার উত্তরটি পাওয়া) অ্যাসিক্রোনাস অ্যাকশন নির্মাতাদের সাথে ডিল করার জন্য, সম্ভবত সবচেয়ে জনপ্রিয় মিডলওয়্যার হ'ল রিডেক্স-থাঙ্ক এবং এটি আপনাকে অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের সাথে ডিল করার জন্য সহায়তা করবে।

মিডলওয়্যারগুলির আরও অনেক ধরণের রয়েছে যা আপনাকে অ্যাসিনক্রোনাস অ্যাকশন নির্মাতাদের সাথে ডিল করতে সহায়তা করে।


1

প্রশ্নের উত্তর দিতে:

কেন ধারক উপাদান অ্যাসিঙ্ক এপিআই কল করতে পারে না এবং তারপরে ক্রিয়াগুলি প্রেরণ করতে পারে?

আমি কমপক্ষে দুটি কারণে বলব:

প্রথম কারণটি উদ্বেগের বিচ্ছেদ, এটি action creatorকল করা apiএবং ডেটা ফেরত পাওয়া কাজ নয়, আপনাকে আপনার action creator function, এবং action typeএবং একটিতে দুটি যুক্তি দিতে হবেpayload

দ্বিতীয় কারণ হ'ল redux storeবাধ্যতামূলক ক্রিয়া ধরণের এবং allyচ্ছিকভাবে একটি সমতল অবজেক্টের জন্য অপেক্ষা করা কারণpayload (তবে এখানে আপনাকেও পেলোডটি পাস করতে হবে) ।

ক্রিয়া স্রষ্টা নীচের মত একটি সরল বস্তু হওয়া উচিত:

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

আর কাজ Redux-Thunk midlewareকরার dispacheআপনার ফলাফল api callউপযুক্ত করতে action


0

কোনও এন্টারপ্রাইজ প্রকল্পে কাজ করার সময়, মাঝারি ওয়্যারে প্রচুর প্রয়োজনীয়তা পাওয়া যায় যেমন (সাগা) সাধারণ অ্যাসিনক্রোনাস প্রবাহে পাওয়া যায় না, নীচে কিছু রয়েছে:

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

তালিকাটি কেবলমাত্র সাগা ডকুমেন্টেশনের উন্নত বিভাগটি পর্যালোচনা করে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.