2019: চেষ্টা করুন হুকস + প্রতিশ্রুতি ডিবাউনিং করে
আমি কীভাবে এই সমস্যাটি সমাধান করব তার সর্বাধিক আধুনিক সংস্করণ। আমি ব্যবহার করব:
এটি কিছু প্রাথমিক ওয়্যারিং তবে আপনি নিজেরাই আদিম ব্লকগুলি রচনা করছেন এবং আপনি নিজের কাস্টম হুক তৈরি করতে পারেন যাতে আপনাকে কেবল একবার এটি করা দরকার।
// Generic reusable hook
const useDebouncedSearch = (searchFunction) => {
// Handle the input text state
const [inputText, setInputText] = useState('');
// Debounce the original search async function
const debouncedSearchFunction = useConstant(() =>
AwesomeDebouncePromise(searchFunction, 300)
);
// The async callback is run each time the text changes,
// but as the search function is debounced, it does not
// fire a new request on each keystroke
const searchResults = useAsync(
async () => {
if (inputText.length === 0) {
return [];
} else {
return debouncedSearchFunction(inputText);
}
},
[debouncedSearchFunction, inputText]
);
// Return everything needed for the hook consumer
return {
inputText,
setInputText,
searchResults,
};
};
এবং তারপরে আপনি আপনার হুক ব্যবহার করতে পারেন:
const useSearchStarwarsHero = () => useDebouncedSearch(text => searchStarwarsHeroAsync(text))
const SearchStarwarsHeroExample = () => {
const { inputText, setInputText, searchResults } = useSearchStarwarsHero();
return (
<div>
<input value={inputText} onChange={e => setInputText(e.target.value)} />
<div>
{searchResults.loading && <div>...</div>}
{searchResults.error && <div>Error: {search.error.message}</div>}
{searchResults.result && (
<div>
<div>Results: {search.result.length}</div>
<ul>
{searchResults.result.map(hero => (
<li key={hero.name}>{hero.name}</li>
))}
</ul>
</div>
)}
</div>
</div>
);
};
আপনি এই উদাহরণটি এখানে চলমান দেখতে পাবেন এবং আরও তথ্যের জন্য আপনার প্রতিক্রিয়া-অ্যাসিঙ্ক-হুক ডকুমেন্টেশনটি পড়া উচিত ।
2018: চেষ্টা করুন প্রতিশ্রুতি ডিবাউনিং করে
অযথা অনুরোধ সহ ব্যাকএন্ডে প্লাবন এড়াতে আমরা প্রায়শই এপিআই কলগুলি ডাবনো করতে চাই।
2018 সালে, কলব্যাকের সাথে কাজ করা (লোড্যাশ / ইন্ডোরস্কোর) আমার কাছে খারাপ এবং ত্রুটি-প্রবণ মনে হচ্ছে। স্বেচ্ছাসেবী ক্রমে সমাধান হওয়া এপিআই কলগুলির কারণে বয়লারপ্লেট এবং সম্মতি সংক্রান্ত সমস্যার মুখোমুখি হওয়া সহজ।
আপনার যন্ত্রণার সমাধানের জন্য প্রতিক্রিয়াটিকে সামনে রেখে আমি একটি ছোট্ট লাইব্রেরি তৈরি করেছি: দারুণ-প্রত্যাশা-প্রতিশ্রুতি ।
এটি এর চেয়ে বেশি জটিল হওয়া উচিত নয়:
const searchAPI = text => fetch('/search?text=' + encodeURIComponent(text));
const searchAPIDebounced = AwesomeDebouncePromise(searchAPI, 500);
class SearchInputAndResults extends React.Component {
state = {
text: '',
results: null,
};
handleTextChange = async text => {
this.setState({ text, results: null });
const result = await searchAPIDebounced(text);
this.setState({ result });
};
}
ঘোষিত কার্যটি নিশ্চিত করে যে:
- এপিআই কলগুলি চালু করা হবে
- উদ্বিগ্ন ফাংশন সর্বদা একটি প্রতিশ্রুতি দেয়
- কেবলমাত্র শেষ কলের প্রত্যাশিত প্রতিশ্রুতি সমাধান হবে
- একক
this.setState({ result });
এপিআই কল প্রতি ঘটবে
অবশেষে, আপনি যদি অন্য উপাদানটি আনমাউন্ট করেন তবে আপনি অন্য কৌশল যুক্ত করতে পারেন:
componentWillUnmount() {
this.setState = () => {};
}
নোট করুন যে পর্যবেক্ষণগুলি (আরএক্সজেএস) ইনপুটগুলি ডিবিউ করার জন্যও দুর্দান্ত ফিট হতে পারে তবে এটি আরও শক্তিশালী বিমূর্ততা যা সঠিকভাবে শিখতে / ব্যবহার করা আরও কঠিন হতে পারে।
<2017: এখনও কলব্যাক ডিবাউনিং ব্যবহার করতে চান?
এখানে গুরুত্বপূর্ণ অংশটি হ'ল উপাদান উপাদান হিসাবে একক ডিবাউন্সড (বা থ্রোটলড) ফাংশন তৈরি করা । আপনি প্রতিবারই ডিবাউন (বা থ্রোটল) ফাংশনটি পুনরায় তৈরি করতে চান না এবং আপনি একই ধরণের ডিফল্ট ফাংশনটি ভাগ করে নেওয়ার জন্য একাধিক উদাহরণ চাইবেন না।
আমি এই উত্তরে একটি ডিবাউনিং ফাংশনটি সংজ্ঞায়িত করছি না কারণ এটি সত্যিই প্রাসঙ্গিক নয়, তবে এই উত্তরটি _.debounce
আন্ডারস্কোর বা লোড্যাশের পাশাপাশি কোনও ব্যবহারকারী-সরবরাহিত ডিবাউনিং ফাংশন দিয়ে পুরোপুরি সূক্ষ্মভাবে কাজ করবে ।
ভাল ধারণা:
যেহেতু উত্সাহিত ফাংশনগুলি রাষ্ট্রীয়, তাই আমাদের উপাদান উপাদানগুলির জন্য প্রতি একটি ডেঞ্চড ফাংশন তৈরি করতে হবে ।
ES6 (শ্রেণি সম্পত্তি) : প্রস্তাবিত
class SearchBox extends React.Component {
method = debounce(() => {
...
});
}
ES6 (শ্রেণি নির্মাতা)
class SearchBox extends React.Component {
constructor(props) {
super(props);
this.method = debounce(this.method.bind(this),1000);
}
method() { ... }
}
ES5
var SearchBox = React.createClass({
method: function() {...},
componentWillMount: function() {
this.method = debounce(this.method.bind(this),100);
},
});
জেএসফিডাল দেখুন : 3 টি দৃষ্টান্ত প্রতি মুহূর্তে 1 লগ এন্ট্রি তৈরি করছে (এটি বিশ্বব্যাপী 3 করে)।
ভালো বুদ্ধি নই:
var SearchBox = React.createClass({
method: function() {...},
debouncedMethod: debounce(this.method, 100);
});
এটি কাজ করবে না, কারণ শ্রেণি বিবরণ অবজেক্ট তৈরির সময়, this
বস্তুটি নিজেই তৈরি হয় না। this.method
আপনি যা প্রত্যাশা করেন তা ফিরিয়ে দেয় না কারণ this
প্রসঙ্গটি নিজেই অবজেক্ট নয় (যা বাস্তবে এখনও বিটিডব্লিউ তৈরি হয়নি যেমন এটি তৈরি হচ্ছে)।
ভালো বুদ্ধি নই:
var SearchBox = React.createClass({
method: function() {...},
debouncedMethod: function() {
var debounced = debounce(this.method,100);
debounced();
},
});
এবার আপনি কার্যকরভাবে একটি ডিবনসড ফাংশন তৈরি করছেন যা আপনার কল করে this.method
। সমস্যাটি হ'ল আপনি প্রতিটি debouncedMethod
কলটিতে এটিকে পুনরায় তৈরি করছেন, সুতরাং সদ্য নির্মিত ডাবনো ফাংশনটি পূর্ববর্তী কলগুলি সম্পর্কে কিছুই জানে না! আপনার অবশ্যই একই সময়ের সাথে একই পুনঃব্যবহার করা ফাংশনটি পুনরায় ব্যবহার করতে হবে বা ডিবাউনিংটি ঘটবে না।
ভালো বুদ্ধি নই:
var SearchBox = React.createClass({
debouncedMethod: debounce(function () {...},100),
});
এটি এখানে কিছুটা জটিল।
ক্লাসের সমস্ত মাউন্ট করা দৃষ্টান্ত একই উদ্রেক করা ফাংশন ভাগ করবে এবং বেশিরভাগ ক্ষেত্রে এটি আপনি চান না! জেএসফিডাল দেখুন : 3 টি উদাহরণ বিশ্বব্যাপী কেবলমাত্র 1 লগ এন্ট্রি সরবরাহ করছে।
আপনাকে প্রতিটি উপাদান উপাদানগুলির জন্য একটি ডিবাউন্ডড ফাংশন তৈরি করতে হবে এবং ক্লাস পর্যায়ে একক ডিবাউন্সড ফাংশন নয়, প্রতিটি উপাদান উদাহরণ দ্বারা ভাগ করা হবে।
রিঅ্যাক্টের ইভেন্ট পুলিংয়ের যত্ন নিন
এটি সম্পর্কিত কারণ আমরা প্রায়শই ডিওএম ইভেন্টগুলি ডাবনো বা থ্রোট্ট করতে চাই।
প্রতিক্রিয়া হিসাবে, SyntheticEvent
আপনি কলব্যাকগুলিতে প্রাপ্ত ইভেন্ট অবজেক্টগুলি (অর্থাত্, পোল্ড করা হয় (এটি এখন নথিভুক্ত । এর অর্থ হ'ল ইভেন্ট কলব্যাক কল করার পরে, আপনি প্রাপ্ত সিন্থেটিক ইভেন্টকে জিসির চাপ হ্রাস করার জন্য খালি বৈশিষ্ট্যযুক্ত পুলে ফিরিয়ে দেওয়া হবে।
সুতরাং আপনি যদি SyntheticEvent
মূল কলব্যাকের জন্য সংযোজনীয়ভাবে বৈশিষ্ট্যগুলি অ্যাক্সেস করেন (তবে আপনি থ্রোল্ট / ডেবিউন করলে এটি হতে পারে), আপনার যে বৈশিষ্ট্যগুলি অ্যাক্সেস করা হবে তা মোছা হতে পারে। যদি আপনি চান ইভেন্টটি আর কখনও পুনরায় পুলে না ফেলা যায়, তবে আপনি এই persist()
পদ্ধতিটি ব্যবহার করতে পারেন ।
অবিরাম (ডিফল্ট আচরণ: পুল করা ইভেন্ট) ছাড়াই
onClick = e => {
alert(`sync -> hasNativeEvent=${!!e.nativeEvent}`);
setTimeout(() => {
alert(`async -> hasNativeEvent=${!!e.nativeEvent}`);
}, 0);
};
২ য় (অ্যাসিঙ্ক) মুদ্রণ করবে hasNativeEvent=false
কারণ ইভেন্টের বৈশিষ্ট্য পরিষ্কার করা হয়েছে।
জেদ সহ
onClick = e => {
e.persist();
alert(`sync -> hasNativeEvent=${!!e.nativeEvent}`);
setTimeout(() => {
alert(`async -> hasNativeEvent=${!!e.nativeEvent}`);
}, 0);
};
২ য় (অ্যাসিঙ্ক) মুদ্রণ করবে hasNativeEvent=true
কারণ persist
ইভেন্টটি আপনাকে পুলটিতে ফিরিয়ে দেওয়া এড়াতে দেয়।
আপনি এই 2 টি আচরণ এখানে পরীক্ষা করতে পারেন: জেএসফিডাল
থ্রোটল / ডাবনো ফাংশনটি ব্যবহারের উদাহরণের জন্য জুলেনের উত্তর পড়ুন persist()
।
debounce
। এখানে, কখনonChange={debounce(this.handleOnChange, 200)}/>
, এটিdebounce function
প্রতিবার প্রার্থনা করবে । তবে, আসলে আমাদের যা প্রয়োজন তা হ'ল ফাংশনটি ডেকে আনা যা ডাবনো ফাংশনটি ফিরে আসে।