React.js এ আত্মপ্রকাশ সম্পাদন করুন


496

আপনি কীভাবে রিঅ্যাক্ট.জেএসে ডেবিউন করবেন?

আমি হ্যান্ডেলঅনচেনজটি চালু করতে চাই।

আমি চেষ্টা করেছি debounce(this.handleOnChange, 200)কিন্তু কাজ করে না।

function debounce(fn, delay) {
  var timer = null;
  return function() {
    var context = this,
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}

var SearchBox = React.createClass({
  render: function() {
    return <input type="search" name="p" onChange={this.handleOnChange} />;
  },

  handleOnChange: function(event) {
    // make ajax call
  }
});

আমি আপনার সাথে একই সমস্যার মুখোমুখি হয়েছি, নীচে চমত্কার উত্তর! তবে আমার মনে হয় আপনি ভুল পদ্ধতি ব্যবহার করেছেন debounce। এখানে, কখন onChange={debounce(this.handleOnChange, 200)}/>, এটি debounce functionপ্রতিবার প্রার্থনা করবে । তবে, আসলে আমাদের যা প্রয়োজন তা হ'ল ফাংশনটি ডেকে আনা যা ডাবনো ফাংশনটি ফিরে আসে।
pingfengafei

উত্তর:


834

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()


3
চমত্কার উত্তর, টাইপ করা বন্ধ করার পরে কয়েক সেকেন্ডের জন্য ফর্ম ক্ষেত্রের রাজ্যটিকে 'কথোপকথন' হিসাবে সেট করার জন্য এটি দুর্দান্ত, এবং তারপরে ফর্ম জমা দেওয়ার বা ব্লুবারে বাতিল করতে সক্ষম হবে
arush_try.com

8
নোট করুন যে ES6- এ কনস্ট্রাক্টরের অভ্যন্তরে আপনার পদ্ধতিটি সংজ্ঞায়িত করার পরিবর্তে (অদ্ভুত মনে হয়) আপনি handleOnChange = debounce((e) => { /* onChange handler code here */ }, timeout)নিজের শ্রেণীর শীর্ষ স্তরে করতে পারেন । আপনি এখনও কার্যকরভাবে একটি উদাহরণ সদস্য নির্ধারণ করছেন তবে এটি একটি সাধারণ পদ্ধতির সংজ্ঞার চেয়ে কিছুটা বেশি দেখাচ্ছে। constructorআপনার যদি ইতিমধ্যে সংজ্ঞায়িত না হয় তবে এর প্রয়োজন নেই । আমি মনে করি এটি বেশিরভাগ শৈলীর পছন্দ।
thom_nic

24
এতে ডিবিউন্ড করা পদ্ধতিটি বাতিল করতে ভুলবেন না componentWillUnmount: this.method.cancel()- অন্যথায় এটি কোনও আনমাউন্টযুক্ত উপাদানটিতে সেটস্টেট করতে চাইবে।
এলাদো

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

2
কেন সমস্ত উত্তরে ফাংশনটি লেখার পরিবর্তে _.ডাবনস অন্তর্ভুক্ত? এই ফাংশনটির জন্য এটি পুরো লাইব্রেরি দরকার?
chifliiiii

217

অনিয়ন্ত্রিত উপাদান

আপনি ব্যবহার করতে পারেন event.persist() পদ্ধতিটি

আন্ডারস্কোর ব্যবহার করে একটি উদাহরণ অনুসরণ করা হয় _.debounce():

var SearchBox = React.createClass({

  componentWillMount: function () {
     this.delayedCallback = _.debounce(function (event) {
       // `event.target` is accessible now
     }, 1000);
  },

  onChange: function (event) {
    event.persist();
    this.delayedCallback(event);
  },

  render: function () {
    return (
      <input type="search" onChange={this.onChange} />
    );
  }

});

সম্পাদনা করুন: এই জেএসফিডেলটি দেখুন


নিয়ন্ত্রিত উপাদান

আপডেট: উপরের উদাহরণটি একটি অনিয়ন্ত্রিত উপাদান দেখায় । আমি সমস্ত সময় নিয়ন্ত্রিত উপাদান ব্যবহার করি তাই উপরের আরও একটি উদাহরণ এখানে, তবে এটি ব্যবহার না করেইevent.persist() "কৌশল" ।

একটি জেএসফিডেল পাশাপাশি উপলব্ধআন্ডারস্কোর ছাড়াই উদাহরণ

var SearchBox = React.createClass({
    getInitialState: function () {
        return {
            query: this.props.query
        };
    },

    componentWillMount: function () {
       this.handleSearchDebounced = _.debounce(function () {
           this.props.handleSearch.apply(this, [this.state.query]);
       }, 500);
    },

    onChange: function (event) {
      this.setState({query: event.target.value});
      this.handleSearchDebounced();
    },

    render: function () {
      return (
        <input type="search"
               value={this.state.query}
               onChange={this.onChange} />
      );
    }
});


var Search = React.createClass({
    getInitialState: function () {
        return {
            result: this.props.query
        };
    },

    handleSearch: function (query) {
        this.setState({result: query});
    },

    render: function () {
      return (
        <div id="search">
          <SearchBox query={this.state.result}
                     handleSearch={this.handleSearch} />
          <p>You searched for: <strong>{this.state.result}</strong></p>
        </div>
      );
    }
});

React.render(<Search query="Initial query" />, document.body);

সম্পাদনা করুন: 0.12 প্রতিক্রিয়া জানাতে আপডেট হওয়া উদাহরণ এবং জেএসফিডল

সম্পাদনা করুন: সেবাস্তিয়ান লোরবার উত্থাপিত সমস্যাটির সমাধানের জন্য আপডেট করা উদাহরণ

সম্পাদনা: jsfiddle এর সাথে আপডেট হয়েছে যা আন্ডারস্কোর ব্যবহার করে না এবং সরল জাভাস্ক্রিপ্ট ডাবনো ব্যবহার করে।


এটি ইনপুটগুলির জন্য কাজ করে না। ঘোষিত ফাংশনে ইভেন্ট টার্গেটটির আর কোনও মান থাকে না ... সুতরাং ইনপুটটি খালি থাকে।
এটাই

1
কিছুটা জটিল, এটি। প্রপস সম্পর্কে আপনাকে কিছুটা সতর্ক থাকতে হবে। যদি আপনি সেট করেন <input value={this.props.someprop}...তবে এটি ঠিকমতো রেন্ডার হবে না কারণ কীপ্রেসের আপডেট আপডেটের পরে এটি পুনরায় উপাদানটিতে ফিরে আসে না। এটি নিয়ন্ত্রণহীন হওয়ার value=জন্য আপনি যদি খুশি হন তবে তা বাদ দেওয়া ভাল, তবে আপনি যদি মানটি প্রাক-জনবসতি করতে চান এবং / অথবা এটি অন্য কোথাও আবদ্ধ করতে চান তবে স্পষ্টত এটি কাজ করে না।
অ্যালাস্টার মাউ

1
@ অ্যালাস্টারমউ প্রশ্নটির একটি অনিয়ন্ত্রিত উপাদান ছিল, সে কারণেই উত্তরটিও তা পেয়েছে। আমি প্রাক-জনবহুল মান সহ নিয়ন্ত্রিত উপাদানগুলির জন্য একটি বিকল্প সংস্করণ নীচে যুক্ত করেছি।
জুলেন

2
এটি খুব বিপজ্জনক যদি আপনি ডিওএমে একাধিকবার উপাদানটি মাউন্ট করেন, দেখুন স্ট্যাকওভারফ্লো.com
সেবাস্তিয়ান লরবার

4
যদিও এটি দুর্দান্ত উত্তর, আমি persistবিশেষত যখন প্রচুর ইভেন্ট যেমন হতে পারে তখন ব্যবহার করার পরামর্শ দিই না mousemove। আমি দেখেছি কোডটি পুরোপুরি প্রতিক্রিয়াহীন হয়ে উঠেছে। ইভেন্ট কলের ক্ষেত্রে নেটিভ ইভেন্ট থেকে প্রয়োজনীয় ডেটা বের করা এবং তারপরে কেবল ডেটা দিয়ে ডেবিউন্ডড / থ্রোটলড ফাংশন কল করা অনেক বেশি দক্ষ is ইভেন্টটি
সেভাবেই চালিয়ে

31

2019: 'ইউজক্যালব্যাক' রিঅ্যাক্ট হুক ব্যবহার করুন

অনেকগুলি ভিন্ন পদ্ধতির চেষ্টা করার পরে, আমি একটি ইভেন্টের মধ্যে useCallbackব্যবহারের একাধিক কল সমস্যা সমাধানে সবচেয়ে সহজ এবং সর্বাধিক দক্ষ বলে মনে করেছি ।debounceonChange

অনুযায়ী হুক্স এপিআই ডকুমেন্টেশন ,

ইউজক্যালব্যাক কলব্যাকের একটি মুখস্থ সংস্করণ প্রদান করে যা কেবলমাত্র যদি নির্ভরতাগুলির কোনও একটি পরিবর্তিত হয় তবে তা পরিবর্তিত হয়।

নির্ভরতা হিসাবে খালি অ্যারে পাস করা নিশ্চিত করে যে কলব্যাক কেবল একবার একবার কল হয়েছিল। এখানে একটি সাধারণ বাস্তবায়ন:

import React, { useCallback } from "react";
import { debounce } from "lodash";

const handler = useCallback(debounce(someFunction, 2000), []);

const onChange = (event) => {
    // perform any event related action here

    handler();
 };

আশাকরি এটা সাহায্য করবে!


3
আপনি হুক ব্যবহার করছেন তবে দুর্দান্ত সমাধান। তুমি আমাকে আরও কয়েক ঘন্টা হতাশার হাত থেকে বাঁচিয়েছ। ধন্যবাদ!
কার্ল এডওয়ার্ডস

আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন একাধিক কল প্রথম স্থানে ঘটে? না debounce()বিবেচনা না onChange()একই কলব্যাক পদ্ধতি কলব্যাক?
এল আনোনিমো

আমি আমার অ্যাপ্লিকেশনটিতে এটি কাজ করার জন্য এই সমাধানটি সংশোধন করেছি। প্রথমে আমাকে const testFunc2 = useCallback(debounce((text) => console.log('testFunc2() has ran:', text), 1000) , []);ফাংশন উপাদানটির শরীরে লাইনটি সরিয়ে ফেলতে হয়েছিল বা প্রতিক্রিয়াটির বাইরে হুক ব্যবহার সম্পর্কে একটি ত্রুটি বার্তা আউটপুট করে। তারপর onChangeইভেন্ট হ্যান্ডলার: <input type='text' name='name' className='th-input-container__input' onChange={evt => {testFunc2(evt.target.value);}}
এল আনোনিমো

এখানে এই সমাধানটি আমি কীভাবে ব্যবহারকারীকে কোনও ইনপুটে টাইপ করতে দিতে পারি তারপরে টাইপিংয়ের পরে একবার ইনপুট মান সহ একটি ডিবাউন্সড এপিআই কল পাঠাতে। stackoverflow.com/questions/59358092/…
এল আনোনিমো

14

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

import React, {Component} from 'react'
import TextField from 'material-ui/TextField'
import { debounce } from 'lodash'

class TableSearch extends Component {

  constructor(props){
    super(props)

    this.state = {
        value: props.value
    }

    this.changeSearch = debounce(this.props.changeSearch, 250)
  }

  handleChange = (e) => {
    const val = e.target.value

    this.setState({ value: val }, () => {
      this.changeSearch(val)
    })
  }

  render() {

    return (
        <TextField
            className = {styles.field}
            onChange = {this.handleChange}
            value = {this.props.value}
        />
    )
  }
}

14

যদি ইভেন্ট আইটেমটি থেকে আপনার সমস্ত প্রয়োজন হয় তবে ডিওএম ইনপুট উপাদানটি পান, সমাধানটি আরও সহজ - কেবল ব্যবহার করুন ref। নোট করুন যে এর জন্য অ্যান্ডস্কোর দরকার :

class Item extends React.Component {
    constructor(props) {
        super(props);
        this.saveTitle = _.throttle(this.saveTitle.bind(this), 1000);
    }
    saveTitle(){
        let val = this.inputTitle.value;
        // make the ajax call
    }
    render() {
        return <input 
                    ref={ el => this.inputTitle = el } 
                    type="text" 
                    defaultValue={this.props.title} 
                    onChange={this.saveTitle} />
    }
}

2
ডিফল্টভ্যালু আমি যা চাই! আপনাকে অনেক ধন্যবাদ :)
তাজো লেলডজে

14

কিছুক্ষণের জন্য পাঠ্য ইনপুটগুলির সাথে লড়াই করার পরে এবং নিজে থেকে কোনও নিখুঁত সমাধান না পাওয়ার পরে, আমি এটি এনপিএম -এ পেয়েছি : প্রতিক্রিয়া-ডাবনউস-ইনপুট

এখানে একটি সহজ উদাহরণ:

import React from 'react';
import ReactDOM from 'react-dom';
import {DebounceInput} from 'react-debounce-input';

class App extends React.Component {
state = {
    value: ''
};

render() {
    return (
    <div>
        <DebounceInput
        minLength={2}
        debounceTimeout={300}
        onChange={event => this.setState({value: event.target.value})} />

        <p>Value: {this.state.value}</p>
    </div>
    );
}
}

const appRoot = document.createElement('div');
document.body.appendChild(appRoot);
ReactDOM.render(<App />, appRoot);

ডিবাউইনপুট উপাদানগুলি আপনি কোনও সাধারণ ইনপুট উপাদানকে অর্পণ করতে পারেন এমন সমস্ত প্রপাকে গ্রহণ করে। কোডেপেন দিয়ে চেষ্টা করে দেখুন

আমি আশা করি এটি অন্য কাউকেও সহায়তা করে এবং তাদের কিছুটা সময় সাশ্রয় করে।


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

9

আপনার সাথে debounceআসল সিন্থেটিক ইভেন্টটি চারপাশে রাখা দরকার event.persist()। এখানে পরীক্ষিত উদাহরণের সাথে কাজ করা হচ্ছে React 16+

import React, { Component } from 'react';
import debounce from 'lodash/debounce'

class ItemType extends Component {

  evntHandler = debounce((e) => {
    console.log(e)
  }, 500);

  render() {
    return (
      <div className="form-field-wrap"
      onClick={e => {
        e.persist()
        this.evntHandler(e)
      }}>
        ...
      </div>
    );
  }
}
export default ItemType;

কার্যকরী উপাদান সহ, আপনি এটি করতে পারেন -

const Search = ({ getBooks, query }) => {

  const handleOnSubmit = (e) => {
    e.preventDefault();
  }
  const debouncedGetBooks = debounce(query => {
    getBooks(query);
  }, 700);

  const onInputChange = e => {
    debouncedGetBooks(e.target.value)
  }

  return (
    <div className="search-books">
      <Form className="search-books--form" onSubmit={handleOnSubmit}>
        <Form.Group controlId="formBasicEmail">
          <Form.Control type="text" onChange={onInputChange} placeholder="Harry Potter" />
          <Form.Text className="text-muted">
            Search the world's most comprehensive index of full-text books.
          </Form.Text>
        </Form.Group>
        <Button variant="primary" type="submit">
          Search
        </Button>
      </Form>
    </div>
  )
}

তথ্যসূত্র - - https://gist.github.com/elijahmanor/08fc6c8468c994c844213e4a4344a709 - https://blog.revathskumar.com/2016/02/reactjs-used-debounce-in-react-components.html


1
আমি এখনও অবধি পাওয়া দুর্দান্ত সর্বোত্তম বাস্তবায়ন কাজ করে
ভিনসেন্ট টাং

8

আপনি যদি রিডেক্স ব্যবহার করছেন তবে আপনি মিডলওয়্যারের সাহায্যে খুব মার্জিত উপায়ে এটি করতে পারেন। আপনি Debounceমিডলওয়্যারটিকে এই হিসাবে সংজ্ঞায়িত করতে পারেন :

var timeout;
export default store => next => action => {
  const { meta = {} } = action;
  if(meta.debounce){
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      next(action)
    }, meta.debounce)
  }else{
    next(action)
  }
}

তারপরে আপনি অ্যাকশন নির্মাতাদের মধ্যে ডিবাউনিং যোগ করতে পারেন, যেমন:

export default debouncedAction = (payload) => ({
  type : 'DEBOUNCED_ACTION',
  payload : payload,
  meta : {debounce : 300}
}

সেখানে আসলে ইতিমধ্যে মিডলওয়্যার আপনার জন্য এই কাজ করতে npm বন্ধ পেতে পারেন।


আমি মনে করি আমাদের মাঝামাঝি হলে এই মিডলওয়্যারটি অবশ্যই প্রথম applyMiddleware(...)শৃঙ্খলে কার্যকর করা উচিত
ইউসুফ

সময়সীমা আরম্ভ করা হয়নি এবং সেই প্রথম ক্লিয়ারটাইমআউট একটি প্যারামের জন্য অপরিজ্ঞাত সাথে কাজ করবে। ভাল না.
জেসন রাইস

7

ES6 ক্লাস ব্যবহার এবং প্রতিক্রিয়া 15.xx প্রতিক্রিয়া এর ব্যবহার ও lodash.debounce তোমার দর্শন লগ করা refs এখানে ঘটনা লোকসান এই বেঁধে অভ্যন্তরীণভাবে গেছে।

class UserInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInput: ""
    };
    this.updateInput = _.debounce(this.updateInput, 500);
  }


  updateInput(userInput) {
    this.setState({
      userInput
    });
    //OrderActions.updateValue(userInput);//do some server stuff
  }


  render() {
    return ( <div>
      <p> User typed: {
        this.state.userInput
      } </p>
      <input ref = "userValue" onChange = {() => this.updateInput(this.refs.userValue.value) } type = "text" / >
      </div>
    );
  }
}

ReactDOM.render( <
  UserInput / > ,
  document.getElementById('root')
);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<div id="root"></div>


7

ইতিমধ্যে এখানে প্রচুর ভাল তথ্য, তবে সংহত হওয়া। এটি আমার পক্ষে কাজ করে ...

import React, {Component} from 'react';
import _ from 'lodash';

class MyComponent extends Component{
      constructor(props){
        super(props);
        this.handleChange = _.debounce(this.handleChange.bind(this),700);
      }; 

এটি আমার পক্ষে কাজ করে না। রাষ্ট্র আপডেট করে না। যদি আমি _debounce মোড়কে অপসারণ করি তবে এটি কাজ করে। আমি যদিও এই ধারণা ভালোবাসি!
মোড় জার্ট

আমাকে এখানে অনেক প্রস্তাব দেওয়ার জন্য আপনার কোডটি দেখতে হবে, তবে আমি সন্দেহ করি যে এখানে আরও কিছু চলছে ... আশা করি এর থেকে আরও গভীর উত্তরটি কিছুটা আলোকপাত করবে। stackoverflow.com/questions/23123138/…
চাদ স্টিল

6

আপনি লোডাশ ডেবিউন https://lodash.com/docs/4.17.5#debounce পদ্ধতি ব্যবহার করতে পারেন । এটি সহজ এবং কার্যকর।

import * as lodash from lodash;

const update = (input) => {
    // Update the input here.
    console.log(`Input ${input}`);     
}

const debounceHandleUpdate = lodash.debounce((input) => update(input), 200, {maxWait: 200});

doHandleChange() {
   debounceHandleUpdate(input);
}

আপনি নীচের পদ্ধতিটি ব্যবহার করে ডিবাউন পদ্ধতি বাতিল করতে পারেন।

this.debounceHandleUpdate.cancel();

আশা করি এটি আপনাকে সহায়তা করবে। চিয়ার্স !!


5

অবগতির জন্য

এখানে আরও একটি পিসি বাস্তবায়ন:

  • কোনও গ্রন্থাগার ছাড়াই (উদাঃ লোডাশ) ouণ দেওয়ার জন্য
  • প্রতিক্রিয়া হুকস এপিআই ব্যবহার করে

আমি আসা করি এটা সাহায্য করবে :)

import React, { useState, useEffect, ChangeEvent } from 'react';

export default function DebouncedSearchBox({
  inputType,
  handleSearch,
  placeholder,
  debounceInterval,
}: {
  inputType?: string;
  handleSearch: (q: string) => void;
  placeholder: string;
  debounceInterval: number;
}) {
  const [query, setQuery] = useState<string>('');
  const [timer, setTimer] = useState<NodeJS.Timer | undefined>();

  useEffect(() => {
    if (timer) {
      clearTimeout(timer);
    }
    setTimer(setTimeout(() => {
      handleSearch(query);
    }, debounceInterval));
  }, [query]);

  const handleOnChange = (e: ChangeEvent<HTMLInputElement>): void => {
    setQuery(e.target.value);
  };

  return (
    <input
      type={inputType || 'text'}
      className="form-control"
      placeholder={placeholder}
      value={query}
      onChange={handleOnChange}
    />
  );
}

4

এমন একটি use-debounceপ্যাকেজ রয়েছে যা আপনি রিএ্যাকটিজেএস হুক ব্যবহার করতে পারেন।

প্যাকেজের README থেকে:

import { useDebounce } from 'use-debounce';

export default function Input() {
  const [text, setText] = useState('Hello');
  const [value] = useDebounce(text, 1000);

  return (
    <div>
      <input
        defaultValue={'Hello'}
        onChange={(e) => {
          setText(e.target.value);
        }}
      />
      <p>Actual value: {text}</p>
      <p>Debounce value: {value}</p>
    </div>
  );
}

উপরের উদাহরণ থেকে আপনি দেখতে পাচ্ছেন যে valueপ্রতি সেকেন্ডে একবারে (1000 মিলিসেকেন্ড) ভেরিয়েবল আপডেট করার জন্য এটি সেট আপ করা হয়েছে ।


3

সাম্প্রতিক প্রতিক্রিয়া এবং লোডাশের সাথে কেবল আরও একটি বৈকল্পিক।

class Filter extends Component {
  static propTypes = {
    text: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired
  }

  state = {
    initialText: '',
    text: ''
  }

  constructor (props) {
    super(props)

    this.setText = this.setText.bind(this)
    this.onChange = _.fp.debounce(500)(this.onChange.bind(this))
  }

  static getDerivedStateFromProps (nextProps, prevState) {
    const { text } = nextProps

    if (text !== prevState.initialText) {
      return { initialText: text, text }
    }

    return null
  }

  setText (text) {
    this.setState({ text })
    this.onChange(text)
  }

  onChange (text) {
    this.props.onChange(text)
  }

  render () {
    return (<input value={this.state.text} onChange={(event) => this.setText(event.target.value)} />)
  }
}

3

একটি সুন্দর এবং পরিষ্কার সমাধান, এর জন্য কোনও বাহ্যিক নির্ভরতা প্রয়োজন নেই:

প্রতিক্রিয়া হুক্স দিয়ে বিতর্ক

এটি একটি কাস্টম প্লাস ব্যবহারের প্রভাব প্রতিক্রিয়া হুক এবং setTimeout/ clearTimeoutপদ্ধতি ব্যবহার করে।


3

তুমি কি চেষ্টা করেছিলে?

function debounce(fn, delay) {
  var timer = null;
  return function() {
    var context = this,
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}

var SearchBox = React.createClass({
  render: function() {
    return <input type="search" name="p" onChange={this.handleOnChange} />;
  },

  handleOnChange: function(event) {
    debounce(\\ Your handleChange code , 200);
  }
});

2

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

handleOnChange: function (event) {
   debounce(
     $.ajax({})
  , 250);
}

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

2

এখানে একটি উদাহরণ আমি এনেছি যা একটি ডিবাউনারের সাথে অন্য ক্লাসকে আবৃত করে। এটি ডেকরেটার / উচ্চতর আদেশ ক্রিয়ায় পরিণত হওয়ার জন্য নিজেকে সুন্দরভাবে itselfণ দেয়:

export class DebouncedThingy extends React.Component {
    static ToDebounce = ['someProp', 'someProp2'];
    constructor(props) {
        super(props);
        this.state = {};
    }
    // On prop maybe changed
    componentWillReceiveProps = (nextProps) => {
        this.debouncedSetState();
    };
    // Before initial render
    componentWillMount = () => {
        // Set state then debounce it from here on out (consider using _.throttle)
        this.debouncedSetState();
        this.debouncedSetState = _.debounce(this.debouncedSetState, 300);
    };
    debouncedSetState = () => {
        this.setState(_.pick(this.props, DebouncedThingy.ToDebounce));
    };
    render() {
        const restOfProps = _.omit(this.props, DebouncedThingy.ToDebounce);
        return <Thingy {...restOfProps} {...this.state} />
    }
}

2

দেশীয় প্রতিক্রিয়া এবং প্রতিক্রিয়া নেটিভের জন্য শেষের দিকে / 2019 এর জন্য এখন আরও একটি সমাধান রয়েছে :

প্রতিক্রিয়া-debounce-কম্পোনেন্ট

<input>
<Debounce ms={500}>
  <List/>
</Debounce>

এটি একটি উপাদান, সহজেই ব্যবহার করা যায়, ক্ষুদ্র এবং উইডলি সমর্থিত

উদাহরণ:

এখানে চিত্র বর্ণনা লিখুন

import React from 'react';
import Debounce from 'react-debounce-component';

class App extends React.Component {
  constructor (props) {
    super(props);
    this.state = {value: 'Hello'}
  }
  render () {
    return (
      <div>
        <input value={this.state.value} onChange={(event) => {this.setState({value: event.target.value})}}/>
        <Debounce ms={1000}>
          <div>{this.state.value}</div>
        </Debounce>
      </div>
    );
  }
}

export default App;

* আমি এই উপাদানটির নির্মাতা


1

আমি একই সমস্যার সমাধান অনুসন্ধান করছিলাম এবং এই থ্রেডটি জুড়ে এসেছি এবং সেই সাথে আরও কয়েকজন এসেছিলেন তবে তাদের একই সমস্যা ছিল: আপনি যদি কোনও handleOnChangeফাংশন করার চেষ্টা করছেন এবং কোনও ইভেন্টের লক্ষ্য থেকে আপনার যদি প্রয়োজন হয় তবে আপনি পাবেন cannot read property value of nullবা কিছু যেমন ত্রুটি। আমার ক্ষেত্রে, আমার thisচালিত ক্রিয়াটি সম্পাদন করা হওয়ায় আমারও উদ্বোধিত ফাংশনের অভ্যন্তরের প্রসঙ্গটি সংরক্ষণ করা দরকার । এখানে আমার সমাধান, এটি আমার ব্যবহারের ক্ষেত্রে খুব ভাল কাজ করে তাই যে কেউ যদি এই থ্রেডটি দেখতে পায় তবে আমি এটি এখানে রেখে দিচ্ছি:

// at top of file:
var myAction = require('../actions/someAction');

// inside React.createClass({...});

handleOnChange: function (event) {
    var value = event.target.value;
    var doAction = _.curry(this.context.executeAction, 2);

    // only one parameter gets passed into the curried function,
    // so the function passed as the first parameter to _.curry()
    // will not be executed until the second parameter is passed
    // which happens in the next function that is wrapped in _.debounce()
    debouncedOnChange(doAction(myAction), value);
},

debouncedOnChange: _.debounce(function(action, value) {
    action(value);
}, 300)

1

জন্য throttleবা debounceসবচেয়ে ভালো উপায় যাতে আপনি যেকোনো ব্যবহার করতে পারেন একটি ফাংশন স্রষ্টা তৈরি করা যেখানে, উদাহরণস্বরূপ:

  updateUserProfileField(fieldName) {
    const handler = throttle(value => {
      console.log(fieldName, value);
    }, 400);
    return evt => handler(evt.target.value.trim());
  }

এবং আপনার renderপদ্ধতিতে আপনি এটি করতে পারেন:

<input onChange={this.updateUserProfileField("givenName").bind(this)}/>

updateUserProfileFieldআপনি যখনই কল করবেন তখন পদ্ধতিটি একটি পৃথক ফাংশন তৈরি করবে।

দ্রষ্টব্য সরাসরি হ্যান্ডলারটি ফেরত দেওয়ার চেষ্টা করবেন না উদাহরণস্বরূপ এটি কাজ করবে না:

 updateUserProfileField(fieldName) {
    return evt => throttle(value => {
      console.log(fieldName, value);
    }, 400)(evt.target.value.trim());
  }

কেন এটি কাজ করবে না কারণ এটি প্রতিবার একই থ্রোটল ফাংশনটি ব্যবহার না করে ইভেন্টটি ডেকে একটি নতুন থ্রটল ফাংশন উত্পন্ন করবে, সুতরাং মূলত থ্রোটল অকেজো হবে;)

এছাড়াও যদি আপনি ব্যবহার করেন debounceবা throttleআপনার প্রয়োজন না হয় setTimeoutবা clearTimeout, এটি হ'ল আমরা এগুলি ব্যবহার করি: পি


1

এখানে একটি ফাংশন উপাদানগুলিতে আবৃত @ আব্রার পদ্ধতির ব্যবহার করে একটি স্নিপেট রয়েছে (আমরা ইউআইয়ের জন্য ফ্যাব্রিক ব্যবহার করি, কেবল এটি একটি সাধারণ বোতাম দিয়ে প্রতিস্থাপন করুন)

import React, { useCallback } from "react";
import { debounce } from "lodash";

import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button';

const debounceTimeInMS = 2000;

export const PrimaryButtonDebounced = (props) => {

    const debouncedOnClick = debounce(props.onClick, debounceTimeInMS, { leading: true });

    const clickHandlerDebounced = useCallback((e, value) => {

        debouncedOnClick(e, value);

    },[]);

    const onClick = (e, value) => {

        clickHandlerDebounced(e, value);
    };

    return (
        <PrimaryButton {...props}
            onClick={onClick}
        />
    );
}

1

আমার সমাধান হুক ভিত্তিক (টাইপস্ক্রিপ্টে লিখিত)।

আমি 2 প্রধান হুক পেয়েছি useDebouncedValueএবংuseDebouncedCallback

প্রথম - useDebouncedValue

ধরা যাক আমরা একটি অনুসন্ধান বাক্স পেয়েছি, তবে ব্যবহারকারীর 0,5 এর জন্য টাইপ করা বন্ধ করার পরে আমরা সার্ভারকে অনুসন্ধানের ফলাফলের জন্য জানতে চাই

function SearchInput() {
  const [realTimeValue, setRealTimeValue] = useState('');

  const debouncedValue = useDebouncedValue(realTimeValue, 500); // this value will pick real time value, but will change it's result only when it's seattled for 500ms

  useEffect(() => {
    // this effect will be called on seattled values
    api.fetchSearchResults(debouncedValue);
  }, [debouncedValue])

  return <input onChange={event => setRealTimeValue(event.target.value)} />
}

বাস্তবায়ন

import { useState, useEffect } from "react";

export function useDebouncedValue<T>(input: T, time = 500) {
  const [debouncedValue, setDebouncedValue] = useState(input);

  // every time input value has changed - set interval before it's actually commited
  useEffect(() => {
    const timeout = setTimeout(() => {
      setDebouncedValue(input);
    }, time);

    return () => {
      clearTimeout(timeout);
    };
  }, [input, time]);

  return debouncedValue;
}

দ্বিতীয় useDebouncedCallback

এটি কেবলমাত্র আপনার উপাদানগুলির সুযোগগুলিতে একটি 'ডিবাউন্ডড' ফাংশন তৈরি করে।

ধরা যাক আমরা একটি বোতামের সাথে একটি উপাদান পেয়েছি যা আপনার ক্লিক বন্ধ করার পরে 500 মিমি সতর্কতা প্রদর্শন করবে।

function AlertButton() {
  function showAlert() {
    alert('Clicking has seattled');
  }

  const debouncedShowAlert = useDebouncedCallback(showAlert, 500);

  return <button onClick={debouncedShowAlert}>Click</button>
}

বাস্তবায়ন (নোট আমি সহায়ক হিসাবে লড্যাশ / আত্মপ্রকাশ ব্যবহার করছি)

import debounce from 'lodash/debounce';
import { useMemo } from 'react';

export function useDebouncedCallback<T extends (...args: any) => any>(callback: T, wait?: number) {
  const debouncedCallback = useMemo(() => debounce(callback, wait), [callback, wait]);

  return debouncedCallback;
}

0

যারা টিএস ব্যবহার করেন এবং asyncফাংশনগুলি ডাবনো করতে চান তাদের জন্য এখানে একটি কার্যকারী টাইপস্ক্রিপ্ট উদাহরণ's

function debounce<T extends (...args: any[]) => any>(time: number, func: T): (...funcArgs: Parameters<T>) => Promise<ReturnType<T>> {
     let timeout: Timeout;

     return (...args: Parameters<T>): Promise<ReturnType<T>> => new Promise((resolve) => {
         clearTimeout(timeout);
         timeout = setTimeout(() => {
             resolve(func(...args));
         }, time)
     });
 }

0

এখানে একটু দেরি হলেও এটি সাহায্য করা উচিত। এই শ্রেণিটি তৈরি করুন (এটি টাইপস্ক্রিপ্টে লিখিত তবে এটি জাভাস্ক্রিপ্টে রূপান্তরিত করা সহজ)

export class debouncedMethod<T>{
  constructor(method:T, debounceTime:number){
    this._method = method;
    this._debounceTime = debounceTime;
  }
  private _method:T;
  private _timeout:number;
  private _debounceTime:number;
  public invoke:T = ((...args:any[])=>{
    this._timeout && window.clearTimeout(this._timeout);
    this._timeout = window.setTimeout(()=>{
      (this._method as any)(...args);
    },this._debounceTime);
  }) as any;
}

এবং ব্যবহার করতে

var foo = new debouncedMethod((name,age)=>{
 console.log(name,age);
},500);
foo.invoke("john",31);

0

আপনি উত্তেজনা উত্তেজনা ব্যবহার করতে পারেন

function log(server) {
  console.log('connecting to', server);
}

const debounceLog = debounce(log, 5000);
// just run last call to 5s
debounceLog('local');
debounceLog('local');
debounceLog('local');
debounceLog('local');
debounceLog('local');
debounceLog('local');

0

জুলেন দ্রষ্টব্য পড়া এক ধরণের কঠিন, এখানে যে কেউ তাকে শিরোনামের ভিত্তিতে হোঁচট খেয়েছে এবং প্রশ্নের ক্ষুদ্র ক্ষুদ্র বিবরণ নয়, তার পক্ষে ক্লিষ্ট এবং দ্য পয়েন্ট প্রতিক্রিয়ার কোড।

tl; ডাঃ সংস্করণ : আপনি যখন পর্যবেক্ষকদের কাছে আপডেট করবেন পরিবর্তে একটি শিডিয়ুল পদ্ধতি কল করুন এবং পরিবর্তে এটি পর্যবেক্ষকদের অবহিত করবে (বা এজাজ ইত্যাদি সম্পাদন করবে)

উদাহরণস্বরূপ উপাদান jsfiddle সহ jsfiddle সম্পূর্ণ করুন

var InputField = React.createClass({

    getDefaultProps: function () {
        return {
            initialValue: '',
            onChange: null
        };
    },

    getInitialState: function () {
        return {
            value: this.props.initialValue
        };
    },

    render: function () {
        var state = this.state;
        return (
            <input type="text"
                   value={state.value}
                   onChange={this.onVolatileChange} />
        );
    },

    onVolatileChange: function (event) {
        this.setState({ 
            value: event.target.value 
        });

        this.scheduleChange();
    },

    scheduleChange: _.debounce(function () {
        this.onChange();
    }, 250),

    onChange: function () {
        var props = this.props;
        if (props.onChange != null) {
            props.onChange.call(this, this.state.value)
        }
    },

});

3
এটি কি ইনপুটফিল্ডের সমস্ত দৃষ্টান্তের রাজ্য / সময়কে বৈশ্বিক করে তুলবে না, কারণ এটি শ্রেণীর সংজ্ঞা দিয়ে তৈরি করা হয়েছে? হতে পারে এটি আপনি চান, তবে এটি নির্বিশেষে লক্ষ করার মতো।
26 এ ছিনিয়ে আনে

1
বিপজ্জনক যদি ডোমে একাধিক সময় মাউন্ট করা হয়, স্ট্যাকওভারফ্লো.com
সেবাস্তিয়ান লরবার 20'15

2
এটি একটি খারাপ সমাধান, কারণ ডাবল-মাউন্ট সমস্যার কারণে - আপনি সিঙ্গলটনের পরিবর্তনের জন্য আপনার ফাংশনটি তৈরি করছেন এবং এটি কোনও ভাল ধারণা নয়। -1
হেনরিক

0

ব্যবহার করা এড়িয়ে চলুন event.persist()- আপনি সিন্থেটিক ইভেন্টটিকে পুনরায় ব্যবহার করতে চান। আমি মনে করি আপনি ক্লাস বা হুক ব্যবহার করেন কিনা তার সবচেয়ে পরিষ্কার উপায় হ'ল কলব্যাকটি দুটি টুকরোতে বিভক্ত করা:

  1. কোনও বিনা ছাড়াই কলব্যাক
  2. আপনার প্রয়োজন ইভেন্টের কেবলমাত্র টুকরোগুলি কল করে একটি ডিবাউন্ড ফাংশন (যাতে সিন্থেটিক ইভেন্টটি পুনর্ব্যবহার করা যায়)

ক্লাস

handleMouseOver = throttle(target => {
  console.log(target);
}, 1000);

onMouseOver = e => {
  this.handleMouseOver(e.target);
};

<div onMouseOver={this.onMouseOver} />

ক্রিয়াকলাপ

const handleMouseOver = useRef(throttle(target => {
  console.log(target);
}, 1000));

function onMouseOver(e) {
  handleMouseOver.current(e.target);
}

<div onMouseOver={this.onMouseOver} />

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


0

ইউজস্টেট হুক প্রসারিত করুন

import { useState } from "react";
import _ from "underscore"
export const useDebouncedState = (initialState, durationInMs = 500) => {
    const [internalState, setInternalState] = useState(initialState);
    const debouncedFunction = _.debounce(setInternalState, durationInMs);
    return [internalState, debouncedFunction];
};
export default useDebouncedState;

হুক ব্যবহার করুন

import useDebouncedState from "../hooks/useDebouncedState"
//...
const [usernameFilter, setUsernameFilter] = useDebouncedState("")
//...
<input id="username" type="text" onChange={e => setUsernameFilter(e.target.value)}></input>

https://trippingoncode.com/react-debounce-hook/


0

আজ এই সমস্যা মেলে। ব্যবহার করে এটি মীমাংসিত setTimeoutএবং clearTimeout

আমি একটি উদাহরণ দেব যা আপনি মানিয়ে নিতে পারেন:

import React, { Component } from 'react'

const DEBOUNCE_TIME = 500

class PlacesAutocomplete extends Component {
  debounceTimer = null;

  onChangeHandler = (event) => {
    // Clear the last registered timer for the function
    clearTimeout(this.debounceTimer);

    // Set a new timer
    this.debounceTimer = setTimeout(
      // Bind the callback function to pass the current input value as arg
      this.getSuggestions.bind(null, event.target.value), 
      DEBOUNCE_TIME
    )
  }

  // The function that is being debounced
  getSuggestions = (searchTerm) => {
    console.log(searchTerm)
  }

  render() {
    return (
      <input type="text" onChange={this.onChangeHandler} />
    )
  }
}

export default PlacesAutocomplete

আপনি এটির নিজস্ব ফাংশন উপাদানগুলিতে এটি পুনরুদ্ধার করতে পারেন:

import React from 'react'

function DebouncedInput({ debounceTime, callback}) {
  let debounceTimer = null
  return (
    <input type="text" onChange={(event) => {
      clearTimeout(debounceTimer);

      debounceTimer = setTimeout(
        callback.bind(null, event.target.value), 
        debounceTime
      )
    }} />
  )
}

export default DebouncedInput

এবং এটি ব্যবহার করুন:

import React, { Component } from 'react'
import DebouncedInput from '../DebouncedInput';

class PlacesAutocomplete extends Component {
  debounceTimer = null;

  getSuggestions = (searchTerm) => {
    console.log(searchTerm)
  }

  render() {
    return (
      <DebouncedInput debounceTime={500} callback={this.getSuggestions} />
    )
  }
}

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