কার্যকরী রাজ্যহীন উপাদান, খাঁটি কম্পোনেন্ট, কম্পোনেন্ট প্রতিক্রিয়া; পার্থক্যগুলি কি এবং কখন আমাদের ব্যবহার করা উচিত?


188

প্রতিক্রিয়া v15.3.0 থেকে জানতে পেরেছিলাম , বিল্ট-ইন পিউরেন্ডারমিক্সিন সহ প্রসারিত করার জন্য আমাদের কাছে একটি নতুন বেস ক্লাস রয়েছে যা পিউরকম্পোনেন্ট নামে পরিচিত । আমি যা বুঝতে পারি তা হুডের নীচে এটি ভিতরে প্রপসের একটি অগভীর তুলনা নিয়োগ করে ।shouldComponentUpdate

একটি প্রতিক্রিয়া উপাদান সংজ্ঞায়িত করার জন্য এখন আমাদের কাছে 3 টি উপায় রয়েছে:

  1. কার্যকরী রাজ্যহীন উপাদান যা কোনও শ্রেণি প্রসারিত করে না
  2. একটি উপাদান যে প্রসারিত PureComponentবর্গ
  3. Componentক্লাস প্রসারিত একটি সাধারণ উপাদান

কিছু সময় আগে আমরা স্টেটলেস উপাদানগুলিকে খাঁটি উপাদান বা ডাম্প উপাদান হিসাবে ডেকেছিলাম। "খাঁটি" শব্দের পুরো সংজ্ঞাটি এখন প্রতিক্রিয়াতে পরিবর্তিত হয়েছে বলে মনে হয়।

যদিও আমি এই তিনটির মধ্যে মৌলিক পার্থক্যগুলি বুঝতে পারি, কখন কী বেছে নেব তা এখনও নিশ্চিত নই । এছাড়াও প্রত্যেকের পারফরম্যান্স প্রভাব এবং ট্রেড-অফগুলি কী কী?


আপডেট :

এগুলিই আমি স্পষ্ট হওয়ার প্রত্যাশা করি:

  • আমি কি আমার সাধারণ উপাদানগুলি কার্যকরী (সরলতার জন্য) হিসাবে সংজ্ঞায়িত করতে বা PureComponentশ্রেণি বাড়াতে (পারফরম্যান্সের জন্য) হিসাবে বেছে নিতে পারি?
  • পারফরম্যান্সটি কি উত্সাহ দেয় যে আমি যে সরলতার জন্য হারিয়েছি তার জন্য সত্যিকারের বাণিজ্য বন্ধ রয়েছে?
  • আমি Componentযখন সর্বদা PureComponentউন্নত পারফরম্যান্সের জন্য ব্যবহার করতে পারি তখন কি আমার কখনই সাধারণ শ্রেণি বাড়ানো দরকার ?

উত্তর:


315

আপনি কীভাবে সিদ্ধান্ত নেবেন, আমাদের উপাদানগুলির উদ্দেশ্য / আকার / প্রপস / আচরণের ভিত্তিতে আপনি এই তিনটির মধ্যে কীভাবে চয়ন করবেন?

কাস্টম পদ্ধতির সাথে React.PureComponentবা থেকে প্রসারিত করার পারফরম্যান্সের সাথে জড়িত। স্টেটলেস ফাংশনাল উপাদানগুলি ব্যবহার করা একটি "আর্কিটেকচারাল" পছন্দ এবং বাক্সের বাইরে কোনও কার্যকারিতা সুবিধা নেই (এখনও)।React.ComponentshouldComponentUpdate

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

  • প্রসারিত PureComponentআপনি যদি জানেন আপনার আউটপুট সহজ সাজসরঞ্জাম উপর নির্ভর করে / রাজ্য ( "সহজ" কোন নেস্টেড ডাটা স্ট্রাকচার তুলনা যার অর্থ PureComponent সঞ্চালিত হিসাবে একটি অগভীর) এবং আপনার প্রয়োজন / কিছু পারফরম্যান্সের উন্নতি পেতে পারেন।

  • Componentআপনার নিজের প্রসারিত করুন এবং প্রয়োগ করুন shouldComponentUpdateযদি আপনার পরবর্তী / বর্তমান প্রপস এবং রাজ্যের মধ্যে কাস্টম তুলনা লজিক সম্পাদন করে কিছু পারফরম্যান্স লাভের প্রয়োজন হয়। উদাহরণস্বরূপ, আপনি লড্যাশ # isqual ব্যবহার করে দ্রুত একটি গভীর তুলনা সম্পাদন করতে পারেন:

    class MyComponent extends Component {
        shouldComponentUpdate (nextProps, nextState) {
            return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);
        }
    }
    

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

আরো বিস্তারিত

কার্যক্ষম স্টেটলেস উপাদান:

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

পেশাদাররা:

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

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

কনস:

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

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

  • রেফসগুলি সমর্থন করে না: https://github.com/facebook/react/issues/4936

একটি উপাদান যা পিওরকমম্পোনেন্ট শ্রেণি ভিএস প্রসারিত করে একটি সাধারণ উপাদান যা উপাদান শ্রেণিকে প্রসারিত করে:

সিনট্যাক্স PureRenderMixinব্যবহার করে সংজ্ঞায়িত শ্রেণীর সাথে সংযুক্ত হতে পারে এমনটি ব্যবহার করার জন্য প্রতিক্রিয়া জানান React.createClass। মিক্সিন কেবল shouldComponentUpdateপরবর্তী প্রস এবং পরবর্তী অবস্থার মধ্যে অল্প অল্প অল্প তুলনা করে সেখানে কোনও পরিবর্তন হয়েছে কিনা তা পরীক্ষা করে দেখায়। যদি কোনও পরিবর্তন হয় না, তবে পুনরায় রেন্ডার করার দরকার নেই।

আপনি যদি ES6 সিনট্যাক্সটি ব্যবহার করতে চান তবে আপনি মিক্সিন ব্যবহার করতে পারবেন না। সুতরাং সুবিধার জন্য প্রতিক্রিয়া PureComponentআপনাকে ব্যবহারের পরিবর্তে উত্তরাধিকারী এমন একটি শ্রেণি প্রবর্তন করেছিল ComponentPureComponentঠিক shouldComponentUpdateএকই পদ্ধতিতে প্রয়োগ করে PureRendererMixin। এটি বেশিরভাগ সুবিধাজনক জিনিস যাতে আপনার নিজের এটি প্রয়োগ করতে হবে না, বর্তমান / পরবর্তী রাজ্য এবং প্রপসের মধ্যে অগভীর তুলনা সম্ভবত সবচেয়ে সাধারণ দৃশ্য যা আপনাকে কিছু দ্রুত পারফরম্যান্স জিততে পারে।

উদাহরণ:

class UserAvatar extends Component {
    render() {
       return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div>
    }
} 

আপনি দেখতে পারেন যে আউটপুট উপর নির্ভর করে props.imageUrlএবং props.username। যদি কোনও প্যারেন্ট উপাদানগুলিতে আপনি <UserAvatar username="fabio" imageUrl="http://foo.com/fabio.jpg" />একই প্রপসের সাথে রেন্ডার করেন renderতবে আউটপুটটি হুবহু হ'ল এমনকি প্রতিক্রিয়া প্রতিবার কল করবে। মনে রাখবেন যে প্রতিক্রিয়া ডোম পৃথক করে প্রয়োগ করে, তাই ডমটি আসলে আপডেট হয় না। তবুও, ডোম ডিফিংয়ের কাজটি ব্যয়বহুল হতে পারে, সুতরাং এই পরিস্থিতিতে এটি নষ্ট হবে।

তাহলে UserAvatarকম্পোনেন্ট প্রসারিত PureComponentপরিবর্তে, অগভীর তুলনা সঞ্চালিত হয়। এবং যেহেতু প্রপস এবং নেক্সটপ্রোপগুলি একই, renderএকেবারেই বলা হবে না।

প্রতিক্রিয়াতে "খাঁটি" সংজ্ঞা সম্পর্কিত নোট:

সাধারণভাবে, একটি "খাঁটি ফাংশন" এমন একটি ফাংশন যা সর্বদা একই ফলাফলের জন্য একই ইনপুট প্রদানে মূল্যায়ন করে। আউটপুট (প্রতিক্রিয়াটির জন্য, এটিই renderপদ্ধতি দ্বারা ফিরিয়ে দেওয়া হয় ) কোনও ইতিহাস / রাষ্ট্রের উপর নির্ভর করে না এবং এর কোনও পার্শ্ব-প্রতিক্রিয়া নেই (ক্রিয়াকলাপের বাইরে "বিশ্বের" পরিবর্তন করে এমন ক্রিয়াকলাপ)।

প্রতিক্রিয়া হিসাবে, স্টেটলেস উপাদানগুলি উপরোক্ত সংজ্ঞা অনুসারে প্রয়োজনীয় শুদ্ধ উপাদান নয় যদি আপনি "স্টেটলেস" এমন কোনও উপাদান বলেন যা কখনও কল this.setStateকরে না এবং এটি ব্যবহার করে না this.state

প্রকৃতপক্ষে, একটিতে, আপনি PureComponentএখনও জীবনচক্র পদ্ধতিতে পার্শ্ব প্রতিক্রিয়া সম্পাদন করতে পারেন। উদাহরণস্বরূপ আপনি ভিতরে একটি এজাক্স অনুরোধ প্রেরণ componentDidMountকরতে পারেন বা আপনি কোনও ডিওএম গণনা সম্পাদন করতে পারলেন তার মধ্যে একটি ডিভের উচ্চতা গতিশীলভাবে সামঞ্জস্য করতে render

"বোবা উপাদানগুলি" সংজ্ঞার আরও "ব্যবহারিক" অর্থ রয়েছে (কমপক্ষে আমার বোঝার মধ্যে দিয়ে): একটি বোবা উপাদান "প্রপসের মাধ্যমে পিতা বা মাতা উপাদান দ্বারা কী করণীয় তা জানানো হয়, এবং কীভাবে কী করতে হয় তা জানে না তবে প্রপস ব্যবহার করে পরিবর্তে কলব্যাকস।

"স্মার্ট" উদাহরণ AvatarComponent:

class AvatarComponent extends Component {
    expandAvatar () {
        this.setState({ loading: true });
        sendAjaxRequest(...).then(() => {
            this.setState({ loading: false });
        });
    }        

    render () {
        <div onClick={this.expandAvatar}>
            <img src={this.props.username} />
        </div>
    }
}

"বোবা" উদাহরণ AvatarComponent:

class AvatarComponent extends Component {
    render () {
        <div onClick={this.props.onExpandAvatar}>
            {this.props.loading && <div className="spinner" />}
            <img src={this.props.username} />
        </div>
    }
}

শেষ পর্যন্ত আমি বলব যে "বোবা", "স্টেটলেস" এবং "খাঁটি" হ'ল একেবারে পৃথক ধারণা যা কখনও কখনও ওভারল্যাপ করতে পারে তবে এটি সাধারণত আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে।


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

1
সমস্যা নেই. কার্যক্ষম স্টেটলেস উপাদানটির জন্য, এমন একটি পেশাদার / বিভক্ত তালিকা রয়েছে যা আমি আপনাকে সিদ্ধান্ত নিতে বিবেচনা করতে পারি যে এটি উপযুক্ত। যে উত্তর আপনি প্রথম পয়েন্ট? আমি পছন্দের প্রশ্নটি আরও কিছুটা সমাধান করার চেষ্টা করতে যাচ্ছি।
fabio.sussetto

2
প্যারেন্ট উপাদানগুলি আপডেট না হয়ে গেলে কার্যকরী উপাদানগুলি সর্বদা পুনরায় রেন্ডার করা হয়, এমনকি যদি সেগুলি ব্যবহার না করে propsউদাহরণ
অ্যালেক্সএম

1
আমি বেশ কিছু সময় পড়েছি এটি সবচেয়ে ব্যাপক উত্তর। মহান কাজ. প্রথম বাক্যটি সম্পর্কে একটি মন্তব্য: প্রসারিত করার সময় PureComponent, আপনার বাস্তবায়ন করা উচিত নয় shouldComponentUpdate()। আপনি যদি বাস্তবে এটি করেন তবে আপনার একটি সতর্কতা দেখতে হবে।
jjramos

1
বাস্তব পারফরম্যান্স লাভের PureComponentজন্য আপনার এমন উপাদানগুলির জন্য ব্যবহার করার চেষ্টা করা উচিত যা নেস্টেড অবজেক্ট / অ্যারে বৈশিষ্ট্যগুলি করে। অবশ্যই আপনাকে কী ঘটছে সে সম্পর্কে সচেতন হতে হবে। যদি আমি সঠিকভাবে বুঝতে পারি, আপনি যদি প্রপস / স্টেটকে সরাসরি পরিবর্তন করতে না পারেন (যা প্রতিক্রিয়া আপনাকে সতর্কতা সহকারে বাধা দেওয়ার চেষ্টা করে) বা বাহ্যিক লাইব্রেরির মাধ্যমে, তবে আপনি সর্বত্র বেশিরভাগ জায়গায় PureComponentপরিবর্তে ব্যবহার করা উচিত Component... ব্যতিক্রম ছাড়া খুব সাধারণ উপাদানগুলির যেখানে এটি ব্যবহার করার জন্য এটি দ্রুততর হতে পারে - দেখুন নিউজ.ইকোম্বিনেটর.com
ম্যাট ব্রাউন

28

প্রতিক্রিয়া নিয়ে আমি কোনও প্রতিভাবান নই, তবে আমার বোঝাপড়া থেকে আমরা প্রতিটি উপাদানকে নিম্নলিখিত পরিস্থিতিতে ব্যবহার করতে পারি

  1. স্টেটলেস উপাদান - এই উপাদানগুলির মধ্যে জীবনচক্র নেই যার ফলে সেই উপাদানগুলি পিতামন্ডলের উপাদানগুলির পুনরাবৃত্ত উপাদানগুলিতে ব্যবহার করা উচিত যেমন পাঠ্য তালিকার রেন্ডারিং যা কেবল তথ্য প্রদর্শন করে এবং সম্পাদনের জন্য কোনও পদক্ষেপ নেই।

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

  3. সাধারণ উপাদান বা জটিল উপাদান - আমি শব্দ জটিল উপাদান ব্যবহার করতাম কারণ সেগুলি সাধারণত পৃষ্ঠার স্তর উপাদান এবং এতে প্রচুর পরিমাণে বাচ্চাদের উপাদান থাকে এবং যেহেতু প্রতিটি শিশু তার নিজস্ব অনন্য পদ্ধতিতে আচরণ করতে পারে তাই আপনি এটি 100% নিশ্চিত হতে পারবেন না প্রদত্ত রাজ্যে একই ফলাফল রেন্ডার করুন। আমি যেমন বলেছি এগুলি সাধারণত ধারক উপাদান হিসাবে ব্যবহার করা উচিত


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

5
  • React.Componentডিফল্ট "সাধারণ" উপাদান। আপনি classকীওয়ার্ড ব্যবহার করে তাদের ঘোষণা করুন এবং extends React.Component। এগুলিকে জীবন শ্রেণির পদ্ধতি, ইভেন্ট হ্যান্ডলার এবং যে কোনও পদ্ধতিতে শ্রেণি হিসাবে ভাবেন।

  • React.PureComponentএটি React.Componentএমন shouldComponentUpdate()একটি ফাংশন যা তার propsএবং এর সাথে অগভীর তুলনা করে কার্যকর করে state। আপনাকে forceUpdate()যদি জানো যে উপাদানটির প্রপস রয়েছে বা রাষ্ট্রীয় নেস্টেড ডেটা রয়েছে যা পরিবর্তিত হয়েছে এবং আপনি পুনরায় রেন্ডার করতে চান তবে আপনাকে ব্যবহার করতে হবে। সুতরাং এগুলি দুর্দান্ত নয় যদি আপনার প্রপস হিসাবে পাস করা বা আপনার রাজ্যের পরিবর্তনে সেট করার সময় অ্যারে বা অবজেক্টগুলি যখন আপনাকে পুনরায় রেন্ডার করার জন্য উপাদানগুলির প্রয়োজন হয়।

  • কার্যকরী উপাদানগুলি হ'ল লাইফসাইकल ফাংশন নেই। তারা কল্পনাশক্তিহীন রাষ্ট্রহীন, তবে তারা এত সুন্দর এবং পরিষ্কার যে আমাদের এখন হুক আছে (যেহেতু ১ 16.৮ এর প্রতিক্রিয়া রয়েছে) সুতরাং আপনার এখনও একটি রাষ্ট্র থাকতে পারে। সুতরাং আমি অনুমান করি যে তারা কেবল "পরিষ্কার উপাদান"।

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