ตอบสนองรหัส“ หลังจากแสดงผล” หรือไม่


367

ฉันมีแอพที่ฉันต้องตั้งความสูงขององค์ประกอบ (เรียกว่า "เนื้อหาของแอพ") แบบไดนามิก ใช้ความสูงของ "chrome" ของแอพและลบออกแล้วตั้งค่าความสูงของ "เนื้อหาแอพ" ให้พอดี 100% ภายในข้อ จำกัด เหล่านั้น นี่เป็นเรื่องง่ายสุด ๆ กับมุมมองวานิลลา JS, jQuery หรือ Backbone แต่ฉันพยายามที่จะเข้าใจว่ากระบวนการที่เหมาะสมสำหรับการทำเช่นนี้ใน React?

ด้านล่างเป็นองค์ประกอบตัวอย่าง ฉันต้องการที่จะสามารถตั้งค่า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
ตอนแรกฉันเป็นเหมือน "flexbox จะแก้ไขได้อย่างไร" ฉันจำคุณสมบัติคอลัมน์ใน Flexbox ได้และมันทำงานได้อย่างมีเสน่ห์!
Oscar Godson

คำตอบ:


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>
    );
  }
});

214
หรือcomponentDidUpdateหากค่าสามารถเปลี่ยนแปลงได้หลังจากการเรนเดอร์ครั้งแรก
zackify

5
ฉันกำลังพยายามเปลี่ยนคุณสมบัติ css ที่ตั้งค่าเป็นช่วงการเปลี่ยนภาพเพื่อให้ภาพเคลื่อนไหวเริ่มต้นหลังจากแสดงผล น่าเสียดายที่การเปลี่ยน CSS ในcomponentDidMount()ไม่ได้ทำให้เกิดการเปลี่ยนแปลง
eye_mew

8
ขอบคุณ ชื่อนั้นช่างเข้าใจง่ายจนฉันสงสัยว่าทำไมฉันถึงลองใช้ชื่อที่ไร้สาระเช่น "init" หรือแม้แต่ "เตรียมใช้งาน"
Pawel

13
การเปลี่ยนใน componentDidMount นั้นเร็วเกินไปสำหรับเบราว์เซอร์ ห่อมันใน setTimeout และให้มันไม่มีเวลาจริง เช่นcomponentDidMount: () => { setTimeout(addClassFunction())}หรือใช้ rAF คำตอบด้านล่างนี้ให้คำตอบนี้

3
แน่นอนที่สุดนี้ไม่ทำงาน หากคุณได้รับรายชื่อโหนดจากนั้นลองวนซ้ำตามรายการโหนดคุณจะพบความยาวเท่ากับ 0 การทำ setTimeout และรอ 1 วินาทีทำงานให้ฉัน น่าเสียดายที่มันไม่ปรากฏปฏิกิริยาตอบสนองมีวิธีการที่รออย่างแท้จริงจนกว่าหลังจากที่มีการแสดงผล DOM
NickJ

241

ข้อเสียเปรียบประการหนึ่งของการใช้componentDidUpdateหรือcomponentDidMountคือการใช้งานจริงก่อนที่องค์ประกอบ dom จะถูกวาดขึ้นมา แต่หลังจากที่พวกเขาถูกส่งผ่านจาก React ไปยัง DOM ของเบราว์เซอร์

พูดเช่นหากคุณต้องการตั้งค่า node.scrollHeight ให้เป็น node ที่แสดงผลแล้ว scrollTop ดังนั้นองค์ประกอบ DOM ของ React อาจไม่เพียงพอ คุณต้องรอจนกว่าองค์ประกอบต่างๆจะถูกทาสีเพื่อให้ได้ความสูง

สารละลาย:

ใช้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 ไม่เพียงพอสำหรับฉัน ฉันต้องแฮ็คมันด้วย window.setTimeout Argggghhhhhh !!!!!
อเล็กซ์

2
แปลก อาจจะมีการเปลี่ยนแปลงใน React เวอร์ชันล่าสุดฉันไม่คิดว่าจำเป็นต้องเรียกร้องให้ร้องขอ AnimationFrame เอกสารอธิบายว่า: "เรียกใช้ทันทีหลังจากการอัพเดทส่วนประกอบถูกล้างไปที่ DOM วิธีนี้ไม่ได้เรียกใช้สำหรับการเรนเดอร์เริ่มต้นใช้สิ่งนี้เป็นโอกาสในการทำงานบน DOM เมื่อองค์ประกอบได้รับการปรับปรุง" ... เช่น ถูกล้างข้อมูลโหนด DOM ควรมีอยู่ - facebook.github.io/react/docs/…
Jim Soho

1
@JimSoho ฉันหวังว่าคุณพูดถูกว่าแก้ไขแล้ว แต่ไม่มีอะไรใหม่ในเอกสารนั้น นี่เป็นกรณีขอบที่มีการอัพเดท Dom ไม่เพียงพอและเป็นสิ่งสำคัญที่เราต้องรอวงจรสี ฉันพยายามที่จะสร้างซอกับรุ่นใหม่และเก่า แต่ฉันไม่สามารถสร้างองค์ประกอบที่ซับซ้อนพอที่จะแสดงให้เห็นถึงปัญหาแม้จะย้อนกลับไปไม่กี่รุ่น ...
เกรแฮม P Heath

3
@ เนปจูนพูดอย่างเคร่งครัด "[RAF] เรียกว่า [... ] ก่อนทาสีใหม่ ... " - [ developer.mozilla.org/en-US/Apps/Fundamentals/Performance/ ...... ] ในสถานการณ์นี้โหนดยังคงต้องการโครงร่างที่คำนวณโดย DOM (aka "reflowed") สิ่งนี้ใช้ RAF เป็นวิธีการกระโดดจากก่อนเค้าโครงเพื่อหลังเค้าโครง เอกสารเบราว์เซอร์จาก Elm เป็นสถานที่ที่ดีสำหรับข้อมูลเพิ่มเติม: elmprogramming.com/virtual-dom.html#how-browsers-render-html
Graham P Heath

1
_this.getDOMNode is not a functionรหัสนี้คืออะไร
OZZIE

104

จากประสบการณ์ของฉันwindow.requestAnimationFrameยังไม่เพียงพอที่จะทำให้แน่ใจว่า DOM ถูกเรนเดอร์ / รีโฟลว์โดยสมบูรณ์componentDidMountแล้ว ฉันมีรหัสทำงานที่เข้าถึง DOM ทันทีหลังจากการcomponentDidMountโทรและการใช้เพียงอย่างเดียวwindow.requestAnimationFrameจะส่งผลให้องค์ประกอบที่มีอยู่ใน DOM; อย่างไรก็ตามการอัปเดตมิติขององค์ประกอบยังไม่ได้รับการสะท้อนเนื่องจากยังไม่มีการรีโฟลว์

วิธีเดียวที่เชื่อถือได้อย่างแท้จริงสำหรับการทำงานนี้คือการห่อวิธีของฉันในsetTimeoutและ a window.requestAnimationFrameเพื่อให้แน่ใจว่าสแต็คการโทรปัจจุบันของ React ได้รับการเคลียร์ก่อนที่จะลงทะเบียนสำหรับการเรนเดอร์เฟรมถัดไป

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

ถ้าฉันต้องคาดเดาว่าทำไมสิ่งนี้จึงเกิดขึ้น / จำเป็นฉันจะเห็นการปรับปรุงการทำซ้ำ DOM ของแบตช์และไม่ได้ใช้การเปลี่ยนแปลงกับ DOM จริง ๆ จนกระทั่งหลังจากสแต็กปัจจุบันเสร็จสมบูรณ์

ท้ายที่สุดหากคุณใช้การวัด DOM ในโค้ดที่คุณใช้หลังจากการเรียกกลับแบบตอบกลับคุณอาจต้องการใช้วิธีนี้


1
คุณต้องการ setTimeout หรือ requestAnimationFrame เท่านั้นไม่ใช่ทั้งสองอย่าง

7
โดยปกติแล้ว - คุณถูกต้อง อย่างไรก็ตามในบริบทของวิธี componentDidMount ของ React หากคุณแนบ requestAnimationFrame ก่อนที่สแต็กนั้นจะเสร็จสิ้น DOM อาจไม่ได้รับการอัพเดตอย่างสมบูรณ์ ฉันมีรหัสที่ทำซ้ำพฤติกรรมนี้อย่างสม่ำเสมอในบริบทของการเรียกกลับของ React วิธีเดียวที่จะแน่ใจได้ว่าโค้ดของคุณกำลังทำงาน (อีกครั้งในกรณีใช้งาน React นี้โดยเฉพาะ) หลังจากที่ DOM ได้อัปเดตแล้วจะอนุญาตให้สแต็กการโทรว่างก่อนด้วย setTimeout
Elliot Chong

6
คุณจะสังเกตเห็นความคิดเห็นอื่น ๆ ข้างต้นซึ่งกล่าวถึงต้องใช้วิธีแก้ปัญหาเดียวกันเช่น: stackoverflow.com/questions/26556436/react-after-render-code/… นี่เป็นวิธีที่เชื่อถือได้ 100% สำหรับกรณีการใช้งาน React นี้เท่านั้น ถ้าฉันต้องเดาว่ามันอาจเป็นเพราะ React batching update ตัวเองซึ่งอาจไม่ถูกนำไปใช้ใน stack ปัจจุบัน (ดังนั้นการชะลอการร้องขอ RequestAnimationFrame ไปยังเฟรมถัดไป
Elliot Chong

4
ฉันคิดว่าคุณอาจจำเป็นต้องจัดการกับเรื่องภายใน JS ของคุณ ... altitudelabs.com/blog/what-is-the-javascript-event-loop stackoverflow.com/questions/8058612/
Elliot Chong

2
การรอสายเรียกซ้อนเพื่อล้างไม่ชัดเจนว่าเป็น "วิธีไร้สาระ" ในการพูดคุยเกี่ยวกับเหตุการณ์วนรอบ แต่สำหรับตัวเขาเองฉันเดาว่า ...
Elliot Chong

17

เพียงแค่อัปเดตคำถามนี้ด้วยเมธอด Hook ใหม่คุณสามารถใช้useEffecthook:

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.
         ...
     }, [])
}

ตามเอกสารของ React useLayoutEffect จะเกิดขึ้นหลังจากการกลายพันธุ์ DOM ทั้งหมดreactjs.org/docs/hooks-reference.html#uselayouteffect
Philippe Hebert

จริง แต่มันทำงานก่อนโครงร่างมีโอกาสทาสีUpdates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.ฉันจะแก้ไข
P Fuster

คุณรู้หรือไม่ว่า useEffect ทำงานหลังจากการเบราว์เซอร์ใหม่ จะปลอดภัยหรือไม่ที่จะขอเลื่อนองค์ประกอบความสูงด้วย useEffect
eMontielG

ปลอดภัยสำหรับ useEffect
P Fuster เมื่อ

13

คุณสามารถเปลี่ยนสถานะจากนั้นทำการคำนวณในการโทรกลับ setStateการเรียกกลับตามเอกสารของ React นี่คือ "รับประกันว่าจะเริ่มทำงานหลังจากใช้งานการอัพเดท"

สิ่งนี้ควรทำ 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
นี่คือคำตอบที่ฉันโปรดปราน รหัสรีแอคทีฟที่สะอาดและดี
phatmann

1
นี่เป็นคำตอบที่ยอดเยี่ยม! ขอบคุณ!
ไบรอัน Jyh Herng ปากช่อง

1
นี่คือสิ่งที่สวยงามโหวตความคิดเห็นนี้ขึ้น!
bingeScripter

11

ฉันรู้สึกว่าโซลูชันนี้สกปรก แต่เราไปที่นี่:

componentDidMount() {
    this.componentDidUpdate()
}

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

ตอนนี้ฉันกำลังจะไปนั่งที่นี่และรอการโหวตลง


5
คุณควรเคารพวงจรชีวิตส่วนประกอบของ React
TúbalMartín

2
@ TúbalMartínฉันรู้ หากคุณมีวิธีที่ดีกว่าในการเข้าถึงผลลัพธ์เดียวกันอย่าลังเลที่จะแบ่งปัน
Jaakko Karhu

8
อืม +1 เป็นรูปเป็นร่างสำหรับ "นั่งที่นี่และรอการโหวตลง" ชายผู้กล้าหาญ ; ^)
รัฟฟิน

14
ค่อนข้างจะเรียกวิธีการจากวงจรชีวิตทั้งสองจากนั้นคุณไม่ต้องเรียกวงจรจากรอบอื่น ๆ
Tjorriemorrie

1
componentWillReceiveProps ควรทำสิ่งนี้
Pablo

8

React มีเมธอดรอบการทำงานไม่กี่ตัวที่ช่วยในสถานการณ์เหล่านี้รายการรวมถึง แต่ไม่ จำกัด เฉพาะgetInitialState, getDefaultProps, componentWillMount, componentDidMountเป็นต้น

ในเคสของคุณและเคสที่ต้องโต้ตอบกับองค์ประกอบ DOM คุณต้องรอจนกระทั่ง dom พร้อมใช้ดังนั้นใช้componentDidMountดังนี้:

/** @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, getDefaultProps, componentWillMount, componentDidMount


องค์ประกอบของฉันทำการเมานต์ก่อนที่จะแสดงผลหน้าทำให้เกิดความล่าช้าอย่างมากในขณะที่การเรียก API โหลดข้อมูล
Jason G

6

ฉันพบปัญหาเดียวกัน

ในสถานการณ์ส่วนใหญ่ที่ใช้การแฮ็ก - ish setTimeout(() => { }, 0)ในการcomponentDidMount()ทำงาน

แต่ไม่ใช่ในกรณีพิเศษ และฉันไม่ต้องการใช้ReachDOM findDOMNodeเนื่องจากเอกสารอธิบายว่า:

หมายเหตุ: findDOMNode เป็นช่องทางหลบหนีที่ใช้ในการเข้าถึงโหนด DOM พื้นฐาน ในกรณีส่วนใหญ่การใช้ช่องหนีนี้จะหมดกำลังใจเพราะมันเจาะส่วนที่เป็นนามธรรม

(ที่มา: 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();
}

ในที่สุดในกรณีของฉันฉันต้องลบ listener ที่สร้างใน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>
    );`
  }

หรือคุณสามารถระบุความสูงของแต่ละส่วนประกอบการตอบสนองโดยใช้ sass ระบุ 2 หลักแรกตอบสนอง div หลักขององค์ประกอบที่มีความกว้างคงที่และจากนั้นความสูงหลัก div องค์ประกอบที่สามด้วยอัตโนมัติ ดังนั้นตามเนื้อหาของ div ที่สามความสูงจะถูกกำหนด


2

ฉันมีปัญหากับพฤติกรรมที่คล้ายกันจริง ๆ ฉันสร้างองค์ประกอบวิดีโอในองค์ประกอบที่มีแอตทริบิวต์ id ดังนั้นเมื่อ RenderDOM.render () สิ้นสุดลงโหลดปลั๊กอินที่ต้องการรหัสเพื่อค้นหาตัวยึดและไม่สามารถหามันได้

setTimeout ที่มี 0ms ภายใน componentDidMount () แก้ไขมัน :)

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

1

จากเอกสารReactDOM.render () :

หากมีการโทรกลับเป็นทางเลือกอุปกรณ์นั้นจะถูกดำเนินการหลังจากส่วนประกอบถูกแสดงหรืออัปเดต


9
คุณสามารถเพิ่มตัวอย่างวิธีใช้สิ่งนี้ได้ไหม ฉันกลับองค์ประกอบจากวิธีการแสดงผลส่วนใหญ่ฉันไม่เรียก render และให้ค่า
dcsan

23
น่าเสียดายที่การติดต่อกลับที่คุณกล่าวถึงนั้นมีให้เฉพาะในระดับบนสุดReactDOM.renderเท่านั้นไม่ใช่สำหรับระดับองค์ประกอบReactElement.render (ซึ่งเป็นหัวข้อที่นี่)
Bramus

1
ตัวอย่างที่นี่จะเป็นประโยชน์
DanV

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

ฉันมีสถานการณ์แปลก ๆ เมื่อฉันต้องการพิมพ์ส่วนประกอบการตอบสนองซึ่งได้รับข้อมูลจำนวนมากและทาสีบนผืนผ้าใบ ฉันได้ลองวิธีการที่กล่าวถึงทั้งหมดแล้วมันไม่ได้ทำงานได้อย่างน่าเชื่อถือสำหรับฉันด้วย requestAnimationFrame ภายใน setTimeout ฉันได้รับผ้าใบว่างเปล่าใน 20% ของเวลาดังนั้นฉันจึงทำสิ่งต่อไปนี้:

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

โดยพื้นฐานแล้วฉันสร้างกลุ่มของ requestAnimationFrame ไม่แน่ใจว่าเป็นความคิดที่ดีหรือไม่ แต่สิ่งนี้ใช้ได้ในกรณี 100% สำหรับฉันจนถึงตอนนี้ (ฉันใช้ 30 เป็นค่าสำหรับตัวแปร n)


0

จริงๆแล้วมีเวอร์ชันที่ง่ายกว่าและสะอาดกว่าการใช้แอนิเมชั่นคำขอหรือหมดเวลา เอี่ยมประหลาดใจว่าไม่มีใครนำมันขึ้นมา: ตัวจัดการโหลดของ vanilla-js หากคุณสามารถทำได้ให้ใช้ component did mount ถ้าเพียงแค่ผูกฟังก์ชั่นบน onload hanlder ขององค์ประกอบ jsx หากคุณต้องการให้ฟังก์ชันเรียกใช้การแสดงผลทุกครั้งให้เรียกใช้งานฟังก์ชั่นก่อนที่จะส่งคืนผลลัพธ์ในฟังก์ชันการแสดงผล รหัสจะมีลักษณะเช่นนี้:

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() - องค์ประกอบกำลังจะถูกลบออกจากเบราว์เซอร์ DOM

1
ไม่ดูหมิ่น แต่วิธีนี้ตอบคำถามได้อย่างไร การแสดงการอัปเดตเกี่ยวกับ ES6 นั้นไม่เกี่ยวข้องกับคำถาม / ไม่เปลี่ยนแปลงอะไรเลย คำตอบที่เก่ากว่าทั้งหมดได้พูดคุยเกี่ยวกับวิธีที่ componentDidMount ไม่ทำงานด้วยตนเอง
dave4jr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.