"রেন্ডার পরে" কোড প্রতিক্রিয়া?


367

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

নীচে একটি উদাহরণ উপাদান রয়েছে। আমি app-contentউইন্ডোজ বিয়োগের আকারের 100% উচ্চতা নির্ধারণ করতে সক্ষম হতে চাই ActionBarএবং BalanceBarতবে যখন আমি সমস্ত কিছু রেন্ডার করা হয় তখন এবং কীভাবে আমি এই প্রতিক্রিয়া শ্রেণিতে গণনার স্টাফ রাখব?

/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar title="Title Here" />
          <BalanceBar balance={balance} />
          <div className="app-content">
            <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

module.exports = AppBase;

4
প্রথমে আমি "ফ্লেক্সবক্স এটি কীভাবে ঠিক করব?" তারপরে আমি ফ্লেক্সবক্সে কলামের বৈশিষ্ট্যটি মনে করেছি এবং এটি একটি কবজির মতো কাজ করেছে!
অস্কার গডসন

উত্তর:


301

componentDidMount ()

আপনার উপাদানটি রেন্ডার হওয়ার পরে এই পদ্ধতিটি একবার কল করা হয়। আপনার কোড তাই দেখতে হবে।

var AppBase = React.createClass({
  componentDidMount: function() {
    var $this = $(ReactDOM.findDOMNode(this));
    // set el height and width etc.
  },

  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
          <div className="inner-wrapper">
            <ActionBar title="Title Here" />
            <BalanceBar balance={balance} />
            <div className="app-content">
              <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

213
অথবা componentDidUpdateযদি প্রথম রেন্ডারের পরে মানগুলি পরিবর্তন করতে পারে।
22-28 এ জ্যাকিফাই করুন

5
আমি একটি সিএসএস সম্পত্তি যা ট্রানজিশনে সেট করা আছে তা পরিবর্তন করার চেষ্টা করছি, যাতে রেন্ডারিংয়ের পরে অ্যানিমেশনটি শুরু হয়। দুর্ভাগ্যক্রমে, সিএসএস এ পরিবর্তন করা componentDidMount()কোনও রূপান্তর ঘটায় না।
eye_mew

8
ধন্যবাদ। নামটি এতটা স্বজ্ঞাত যে আমি অবাক হয়েছি কেন আমি "init" বা এমনকি "আরম্ভকরণ" এর মতো হাস্যকর নাম চেষ্টা করছিলাম।
পাভেল

13
ব্রাউজারের জন্য এটি উপাদান ডিডমাউন্টে পরিবর্তন করা খুব দ্রুত। এটিকে সেটটাইমআউটে মুড়িয়ে রাখুন এবং এটিকে আসল সময় দিন না। যেমন componentDidMount: () => { setTimeout(addClassFunction())}, বা আরএএফ ব্যবহার করুন, এর নীচের উত্তরটি এই উত্তর সরবরাহ করে।

3
এটি অবশ্যই কাজ করে না। যদি আপনি একটি নোড তালিকা পান এবং তারপরে নোড তালিকার উপরে পুনরাবৃত্তি করার চেষ্টা করুন আপনি দৈর্ঘ্য 0 এর সমান দেখতে পাবেন set সেটটাইমআউট করছেন এবং 1 সেকেন্ডের জন্য অপেক্ষা করা আমার জন্য কাজ করেছে। দুর্ভাগ্যক্রমে এটি প্রতিক্রিয়া প্রকাশ করে না এমন একটি পদ্ধতি রয়েছে যা ডম রেন্ডার হওয়ার পরে পর্যন্ত সত্যই অপেক্ষা করে।
নিক

241

ব্যবহারের একটি ত্রুটি componentDidUpdate, বাcomponentDidMount হ'ল এগুলি আসলে ডোম উপাদানগুলি আঁকার আগেই সম্পাদন করা হয় তবে তারা প্রতিক্রিয়া থেকে ব্রাউজারের ডিওমে যাওয়ার পরে।

উদাহরণস্বরূপ বলুন যদি আপনার রেন্ডারড নোড.স্ক্রোলটপটিতে নোড.স্ক্রোলহাইট সেট প্রয়োজন হয়, তবে রিঅ্যাক্টের ডোম উপাদানগুলি যথেষ্ট নাও হতে পারে। উপাদানগুলির উচ্চতা পেতে পেইন্টিং করা না হওয়া পর্যন্ত আপনাকে অপেক্ষা করতে হবে।

সমাধান:

requestAnimationFrameআপনার কোডটি আপনার নতুন রেন্ডার করা অবজেক্টের পেইন্টিংয়ের পরে চলছে কিনা তা নিশ্চিত করতে ব্যবহার করুন

scrollElement: function() {
  // Store a 'this' ref, and
  var _this = this;
  // wait for a paint before running scrollHeight dependent code.
  window.requestAnimationFrame(function() {
    var node = _this.getDOMNode();
    if (node !== undefined) {
      node.scrollTop = node.scrollHeight;
    }
  });
},
componentDidMount: function() {
  this.scrollElement();
},
// and or
componentDidUpdate: function() {
  this.scrollElement();
},
// and or
render: function() {
  this.scrollElement()
  return [...]

29
window.requestAnimationFrame আমার পক্ষে যথেষ্ট ছিল না। উইন্ডো.সেটটাইমআউট দিয়ে আমাকে এটি হ্যাক করতে হয়েছিল। Argggghhhhhh !!!!!
অ্যালেক্স

2
অস্বাভাবিক. সম্ভবত এটি প্রতিক্রিয়াটির সাম্প্রতিকতম সংস্করণে পরিবর্তিত হয়েছে, আমি মনে করি না অনুরোধের জন্য কলটি অ্যানিমেশনফ্রেম প্রয়োজনীয় is ডকুমেন্টেশনটিতে বলা হয়েছে: "উপাদানটির আপডেটগুলি ডিওএম-এ প্রেরণ হওয়ার সাথে সাথেই অনুরোধ করা হয়েছিল This প্রাথমিক পদ্ধতিটি রেন্ডার করার জন্য এই পদ্ধতিটি বলা হয় না the উপাদানটি আপডেট হয়ে যাওয়ার পরে এটি ডিওএম-এ কাজ করার সুযোগ হিসাবে ব্যবহার করুন।" ... অর্থাৎ, এটি ফ্লাশ করা হয়, ডিওএম নোড উপস্থিত থাকা উচিত। - ফেসবুক.
জিম সোহো

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

3
@ নেপটিউয়ানিয়ান কঠোরভাবে বলতে গেলে "[আরএএফ] কে পরবর্তী পুনর্নির্মাণের আগে ... [...] বলা হয় ..." - [ বিকাশকারী.মোজিলা.আর.ইন- ইউএস / অ্যাপস / ফান্ডামেন্টালস / পারফরম্যান্স/… ]। এই পরিস্থিতিতে নোডের ডিওএম (ওরফে "রিফ্লোভড") দ্বারা তার বিন্যাস গণনা করা এখনও দরকার। এটি আরএএফটিকে বিন্যাসের আগে থেকে বিন্যাসের পরে লাফ দেওয়ার উপায় হিসাবে ব্যবহার করে। এলম থেকে ব্রাউজারের ডকুমেন্টেশন আরও জন্য একটি ভাল জায়গা: এলম্প্রাগ্রামিং
গ্রাহাম পি হিথ

1
_this.getDOMNode is not a functionএই কোডটি কি হ্যাক?
ওজজিআইইআই

104

আমার অভিজ্ঞতায় window.requestAnimationFrameএটি নিশ্চিত করার পক্ষে যথেষ্ট ছিল না যে ডিওএম সম্পূর্ণরূপে রেন্ডার / রিফ্লো-সম্পূর্ণ হয়েছিল componentDidMount। আমার কোড চলছে যা একটি componentDidMountকল করার সাথে সাথেই ডমকে অ্যাক্সেস করে এবং একমাত্র ব্যবহারের window.requestAnimationFrameফলে ডিওমে উপস্থিত উপাদান উপস্থিত হতে পারে; যাইহোক, উপাদানটির মাত্রাগুলিতে আপডেটগুলি এখনও প্রতিফলিত হয় না যেহেতু একটি প্রতিস্থাপন এখনও ঘটেনি।

এটির কাজ করার একমাত্র সত্যিকারের নির্ভরযোগ্য উপায় হ'ল পরবর্তী ফ্রেমের রেন্ডারটির জন্য রেজিস্ট্রেশন করার আগে রিএ্যাক্টের বর্তমান কল স্ট্যাকটি সাফ হয়ে যায় তা নিশ্চিত করার জন্য আমার পদ্ধতিটি একটি setTimeoutএবং window.requestAnimationFrameএকটিতে মোড়ানো ।

function onNextFrame(callback) {
    setTimeout(function () {
        requestAnimationFrame(callback)
    })
}

এটি কেন ঘটছে / প্রয়োজনীয় তা নিয়ে যদি আমার জল্পনা শুরু করতে হয় তবে আমি দেখতে পেলাম রিচ ব্যাচিং ডিওএম আপডেটগুলি এবং বর্তমান স্ট্যাকটি সম্পূর্ণ হওয়ার পরে ডিওমে পরিবর্তনগুলি প্রয়োগ না করে।

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


1
আপনার কেবল সেটটাইমআউট বা অনুরোধঅ্যানিমেশনফ্রেম দরকার, দুটোই নয়।

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

6
আপনি উপরের অন্যান্য মন্তব্যগুলি লক্ষ্য করবেন যা একই কর্মসূচীর প্রয়োজনের কথা উল্লেখ করে, যেমন: স্ট্যাকওভারফ্লো / প্রশ্ন / ২265৫6436// / প্রতিক্রিয়া-পরবর্তী- রেন্ডার- কোড / this এই প্রতিক্রিয়া ব্যবহারের ক্ষেত্রে এটি কেবলমাত্র 100% নির্ভরযোগ্য পদ্ধতি। যদি আমি অনুমান করতে হয়েছিল যে এটি প্রতিক্রিয়াশীল ব্যাচিং আপডেটের কারণে হতে পারে যা সম্ভবত বর্তমান স্ট্যাকের মধ্যে প্রয়োগ করা হয় না (সুতরাং ব্যাচটি প্রয়োগ হয়েছে তা নিশ্চিত করার জন্য অনুরোধটি অ্যানিমেশনফ্রেমটি পরবর্তী ফ্রেমে স্থগিত করা হয়)।
এলিয়ট চং

4
আমি মনে করি আপনি আপনার জেএস ইন্টার্নালগুলিতে ব্রাশ করার প্রয়োজন হতে পারে ... উচ্চতাবিজ্ঞান / ব্লগ / কী- এটি-
এলিয়ট চং

2
বর্তমান কল স্ট্যাকটি সাফ হওয়ার জন্য অপেক্ষা করা স্পষ্টতই ইভেন্ট লুপ সম্পর্কে কথা বলার "অযৌক্তিক" উপায় নয়, তবে প্রতিটি তার নিজেরই অনুমান ...
এলিয়ট চং

17

এই প্রশ্নটি নতুন হুক পদ্ধতির সাথে সামান্য আপডেট করার জন্য, আপনি কেবল useEffectহুকটি ব্যবহার করতে পারেন :

import React, { useEffect } from 'react'

export default function App(props) {

     useEffect(() => {
         // your post layout code (or 'effect') here.
         ...
     },
     // array of variables that can trigger an update if they change. Pass an
     // an empty array if you just want to run it once after component mounted. 
     [])
}

এছাড়াও যদি আপনি লেআউট useLayoutEffectপেইন্টটি হুক ব্যবহারের আগে চালাতে চান তবে :

import React, { useLayoutEffect } from 'react'

export default function App(props) {

     useLayoutEffect(() => {
         // your pre layout code (or 'effect') here.
         ...
     }, [])
}

রিঅ্যাক্টের ডকুমেন্টেশন অনুসারে, সমস্ত ডিওএম রূপান্তরিত হওয়ার পরে ব্যবহার লেআউটএফেক্টটি ঘটে reactjs.org/docs/hooks-references.html#uselayouteffect
ফিলিপ হবার্ট

সত্য, তবে লেআউটটিতে Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.আমি সম্পাদনা করব তা আঁকার সুযোগ পাওয়ার আগে এটি চলে না ।
পি ফুস্টার

আপনি কি জানবেন যে ইউজারএফেক্ট ব্রাউজারের রিফ্লোয়ের পরে চলে (যদি প্রতিক্রিয়াটিকে 'পেইন্ট' বলে না)? ইউজএফেক্টের সাথে কোনও উপাদানটির স্ক্রোলহাইটের অনুরোধ করা কি নিরাপদ?
eMontielG

এটি ব্যবহারের জন্য নিরাপদ for
পি ফুস্টার

13

আপনি রাজ্যটি পরিবর্তন করতে পারেন এবং তারপরে আপনার গণনাগুলি সেটস্টেট কলব্যাকে করতে পারেন । প্রতিক্রিয়া ডকুমেন্টেশন অনুসারে, এটি "আপডেট প্রয়োগের পরে আগুনের নিশ্চয়তা"।

এটি করা উচিত componentDidMount কনস্ট্রাক্টরের চেয়ে কোডে বা অন্য কোথাও (একটি আকার পরিবর্তন ইভেন্ট হ্যান্ডলারের মতো)।

এটি একটি ভাল বিকল্প window.requestAnimationFrame এবং এতে কিছু ব্যবহারকারী এখানে উল্লিখিত সমস্যাগুলির মধ্যে নেই (এটির সাথে একত্রিত হওয়ার setTimeoutবা একাধিকবার কল করার প্রয়োজন রয়েছে )। উদাহরণ স্বরূপ:

class AppBase extends React.Component {
    state = {
        showInProcess: false,
        size: null
    };

    componentDidMount() {
        this.setState({ showInProcess: true }, () => {
            this.setState({
                showInProcess: false,
                size: this.calculateSize()
            });
        });
    }

    render() {
        const appStyle = this.state.showInProcess ? { visibility: 'hidden' } : null;

        return (
            <div className="wrapper">
                ...
                <div className="app-content" style={appStyle}>
                    <List items={items} />
                </div>
                ...
            </div>
        );
    }
}

1
এটি আমার প্রিয় উত্তর। পরিষ্কার এবং ভাল আইডেম্যাটিক প্রতিক্রিয়া কোড।
ফাতেমন

1
এটি একটি দুর্দান্ত উত্তর! ধন্যবাদ!
ব্রায়ান জাই হার্ং চং

1
এই সুন্দর, এই মন্তব্য upvote!
বিঞ্জিজক্রিপ্টার

11

আমি মনে করি যে এই সমাধানটি নোংরা, তবে আমরা এখানে যাচ্ছি:

componentDidMount() {
    this.componentDidUpdate()
}

componentDidUpdate() {
    // A whole lotta functions here, fired after every render.
}

এখন আমি এখানে বসে বসে নীচের ভোটের জন্য অপেক্ষা করব।


5
আপনার একটি প্রতিক্রিয়া উপাদান জীবনচক্রকে সম্মান করা উচিত।
তবলাল মার্টিন

2
@ টাবালমার্টন আমি জানি। যদি আপনার একই ফলাফলে পৌঁছানোর আরও ভাল উপায় থাকে তবে নির্দ্বিধায় ভাগ করে নিন।
যাকো কারহু

8
উম, "এখানে বসুন এবং নিচের ভোটের জন্য অপেক্ষা করুন" এর জন্য রূপক +1। সাহসী মানুষ. ; ^)
রাফিন

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

1
উপাদানউইলগ্রিপপ্রোপগুলি এটি করা উচিত
পাবলো

8

প্রতিক্রিয়াটির কয়েকটি লাইফাইসাইক্যাল পদ্ধতি রয়েছে যা এই পরিস্থিতিতে সহায়তা করে, তালিকাগুলি getInitialState, getDefaultProp, উপাদানWillMount, উপাদানডিডমাউন্ট সহ সীমাবদ্ধ নয় ইত্যাদি

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

/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
  componentDidMount: function() {
    ReactDOM.findDOMNode(this).height = /* whatever HEIGHT */;
  },
  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar title="Title Here" />
          <BalanceBar balance={balance} />
          <div className="app-content">
            <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

module.exports = AppBase;

প্রতিক্রিয়াতে লাইফসাইকেল সম্পর্কে আরও তথ্যের জন্য আপনি নীচের লিঙ্কটি দেখতে পারেন: https://facebook.github.io/react/docs/state-and-lifecycle.html

getInitialState, getDefaultProp, উপাদানWillMount, উপাদানDidMount


ডেটা এপিআই কল লোড হওয়ার কারণে পৃষ্ঠাটি রেন্ডার হওয়ার আগে আমার উপাদানটি মাউন্ট চালিয়েছে।
জেসন জি

6

আমি একই সমস্যা মধ্যে দৌড়ে।

সবচেয়ে পরিস্থিতিতে হ্যাক পর ব্যবহার setTimeout(() => { }, 0)মধ্যে componentDidMount()কাজ করেন।

তবে বিশেষ ক্ষেত্রে নয়; এবং ReachDOM findDOMNodeডকুমেন্টেশন বলছে যেহেতু আমি এটি ব্যবহার করতে চাই নি :

দ্রষ্টব্য: findDOMNode হ'ল একটি অন্তর্নিহিত ডোম নোড অ্যাক্সেস করতে ব্যবহৃত হ্যাচ। বেশিরভাগ ক্ষেত্রে, এই পালানোর হ্যাচটির ব্যবহার নিরুত্সাহিত করা হয় কারণ এটি উপাদান বিমূর্তনকে ছিদ্র করে।

(সূত্র: findDOMNode )

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

componentDidMount() {
    // feel this a little hacky? check this: http://stackoverflow.com/questions/26556436/react-after-render-code
    setTimeout(() => {
       window.addEventListener("resize", this.updateDimensions.bind(this));
       this.updateDimensions();
    }, 0);
}

এবং তারপর:

componentDidUpdate() {
    this.updateDimensions();
}

অবশেষে, আমার ক্ষেত্রে আমাকে এতে তৈরি শ্রোতাদের অপসারণ করতে হবে componentDidMount:

componentWillUnmount() {
    window.removeEventListener("resize", this.updateDimensions.bind(this));
}

2

রেন্ডার করার পরে, আপনি নীচের মতো উচ্চতা নির্দিষ্ট করতে পারেন এবং সংশ্লিষ্ট প্রতিক্রিয়া উপাদানগুলির সাথে উচ্চতা নির্দিষ্ট করতে পারেন।

render: function () {
    var style1 = {height: '100px'};
    var style2 = { height: '100px'};

   //window. height actually will get the height of the window.
   var hght = $(window).height();
   var style3 = {hght - (style1 + style2)} ;

    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar style={style1} title="Title Here" />
          <BalanceBar style={style2} balance={balance} />
          <div className="app-content" style={style3}>
            <List items={items} />
          </div>
        </div>
      </div>
    );`
  }

অথবা আপনি স্যাস ব্যবহার করে প্রতিটি প্রতিক্রিয়া উপাদানটির উচ্চতা নির্দিষ্ট করতে পারেন। স্থির প্রস্থের সাথে প্রথম 2 টি বিক্রিয়া উপাদান প্রধান ডিভ এবং তারপরে তৃতীয় উপাদানটি ডিভের উচ্চতা অটো দিয়ে উল্লেখ করুন। সুতরাং তৃতীয় ডিভের সামগ্রীর উপর ভিত্তি করে উচ্চতা নির্ধারিত হবে।


2

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

কম্পোনেন্টডিডমাউন্ট () এর ভিতরে 0 মিমি সহ সেটটাইমআউট এটি ঠিক করেছে :)

componentDidMount() {
    if (this.props.onDidMount instanceof Function) {
        setTimeout(() => {
            this.props.onDidMount();
        }, 0);
    }
}

1

থেকে ReactDOM.render () ডকুমেন্টেশন:

Theচ্ছিক কলব্যাক সরবরাহ করা থাকলে, উপাদানটি রেন্ডার বা আপডেট হওয়ার পরে এটি কার্যকর করা হবে।


9
আপনি কীভাবে এটি ব্যবহার করবেন তার একটি উদাহরণ যোগ করতে পারেন? আমি বেশিরভাগই রেন্ডার পদ্ধতি থেকে উপাদানগুলি ফিরিয়ে দিই, আমি রেন্ডারকে কল করি না এবং মান সরবরাহ করি না।
dcsan

23
দুর্ভাগ্যক্রমে আপনি যে কলব্যাকটিReactDOM.render উল্লেখ করেছেন তা কেবল শীর্ষ স্তরেরReactElement.render জন্য উপলব্ধ, উপাদান স্তরটির জন্য নয় (যা এখানে বিষয়)।
ব্রামাস

1
এখানে উদাহরণ সহায়ক হবে
ডানভি

1
আমি আপনার উত্তরের লিঙ্কটিতে ক্লিক করেছি এবং আপনার উদ্ধৃত লাইনটি আমি খুঁজে পেলাম না এবং আপনার উত্তরে এটি ছাড়া কাজ করার জন্য পর্যাপ্ত তথ্য অন্তর্ভুক্ত নেই। দয়া করে দেখুন stackoverflow.com/help/how-to-answer কিভাবে একটি ভাল প্রশ্ন লিখতে পরামর্শ দেওয়ার জন্য
Benubird

1

আমার জন্য, window.requestAnimationFrameবা এর কোনও সংমিশ্রণ নেইsetTimeout সামঞ্জস্যপূর্ণ ফলাফল উত্পাদিত হয়নি। কখনও কখনও এটি কাজ করে তবে সর্বদা না - বা কখনও কখনও এটি খুব দেরি হয়ে যায়।

আমি window.requestAnimationFrameযতবার প্রয়োজন ততবার লুপ করে এটি ঠিক করেছি ।
(সাধারণত 0 বা 2-3 বার)

মূলটি হ'ল diff > 0পৃষ্ঠাটি আপডেট হওয়ার সময় আমরা এখানে তা নিশ্চিত করতে পারি।

// Ensure new image was loaded before scrolling
if (oldH > 0 && images.length > prevState.images.length) {
    (function scroll() {
        const newH = ref.scrollHeight;
        const diff = newH - oldH;

        if (diff > 0) {
            const newPos = top + diff;
            window.scrollTo(0, newPos);
        } else {
            window.requestAnimationFrame(scroll);
        }
    }());
}

0

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

nRequest = n => range(0,n).reduce(
(acc,val) => () => requestAnimationFrame(acc), () => requestAnimationFrame(this.save)
);

মূলত আমি অনুরোধের একটি শৃঙ্খলা তৈরি করেছি অ্যানিমেশনফ্রেমের, এই ভাল ধারণাটি কিনা তা নিশ্চিত নয় তবে এটি আমার জন্য এখন পর্যন্ত 100% ক্ষেত্রে কাজ করে (আমি এন ভেরিয়েবলের মান হিসাবে 30 ব্যবহার করছি)।


0

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

runAfterRender = () => 
{
  const myElem = document.getElementById("myElem")
  if(myElem)
  {
    //do important stuff
  }
}

render()
{
  this.runAfterRender()
  return (
    <div
      onLoad = {this.runAfterRender}
    >
      //more stuff
    </div>
  )
}

}


-1

ES6পরিবর্তে ক্লাসগুলির সাথে সামান্য আপডেটReact.createClass

import React, { Component } from 'react';

class SomeComponent extends Component {
  constructor(props) {
    super(props);
    // this code might be called when there is no element avaliable in `document` yet (eg. initial render)
  }

  componentDidMount() {
    // this code will be always called when component is mounted in browser DOM ('after render')
  }

  render() {
    return (
      <div className="component">
        Some Content
      </div>
    );
  }
}

এছাড়াও - উপাদানটির জীবনচক্র পদ্ধতির প্রতিক্রিয়া পরীক্ষা করুন: উপাদান লাইফসাইकल

প্রতিটি উপাদান componentDidMountযেমন অনেক অনুরূপ পদ্ধতি আছে ।

  • componentWillUnmount() - ব্রাউজার ডিওএম থেকে উপাদানটি প্রায় সরানো হচ্ছে

1
অসম্মান নেই, তবে এই প্রশ্নের উত্তর কীভাবে দেয়? ES6 এ একটি আপডেট দেখানো আসলেই প্রশ্নের সাথে সম্পর্কিত নয় / কোনও কিছু পরিবর্তন করে না। কম্পোনেন্টডিডমাউন্ট কীভাবে নিজের মতো করে কাজ করে না সে সম্পর্কে ইতিমধ্যে সমস্ত পুরানো উত্তরগুলির মধ্যে কথা রয়েছে।
dave4jr
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.