React "componentDidUpdate" yöntemi ne zaman kullanılır?


110

Düzinelerce Reactdosya yazdım , asla kullanmacomponentDidUpdate yöntem .

Bu yöntemi ne zaman kullanmanız gerektiğine dair tipik bir örnek var mı?

Basit bir demo değil, gerçek hayattan bir örnek istiyorum.

Cevap için teşekkürler!



Yükte bileşenin başlangıç ​​durumunu ayarlamak istediğinizde basit bir durum.
Rajesh

@Rajesh Bunu açıklayabilir misin veya bana bir örnek verebilir misin? Teşekkürler!
slideshowp2

1
Bence en yaygın kullanım durumu, React ile birlikte doğrudan DOM üzerinde çalışan başka kitaplıklara (jQuery, D3 ...) sahip olduğunuz zamandır. Bu tür senaryolarda, diğer kütüphanenin DOM dönüşümlerini gerçekleştirmesi gerekiyorsa, React'in gölge DOM'un gerçek DOM'a boşaltıldığından emin olmak için componentDidUpdate'i kullanmalısınız.
Jorge

1
@ Jorge'nin yorumunu detaylandırmak gerekirse: Bence en yaygın durum React güncellendikten sonra gerçek DOM'dan OKUMAK olacaktır. Örneğin, DOM öğelerinin tam boyutlarını veya görünüm alanındaki DOM öğelerinin konumunu bilmek istediğinizde. Örneğin, yönetmek için tepki vermek istediğiniz animasyonlar veya geçişler için. React oluşturulduktan sonra DOM'u değiştirmek için jQuery'yi kullanmamanızı kesinlikle tavsiye ederim. React + başka bir kitaplığın aynı DOM parçasını değiştirmesi kötü bir fikirdir.
wintvelt

Yanıtlar:


90

Basit bir örnek, kullanıcıdan girdi verilerini toplayan ve ardından söz konusu verileri bir veritabanına yüklemek için Ajax kullanan bir uygulama olabilir. İşte basitleştirilmiş bir örnek (çalıştırmadınız - sözdizimi hataları olabilir):

export default class Task extends React.Component {
  
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: "",
      age: "",
      country: ""
    };
  }

  componentDidUpdate() {
    this._commitAutoSave();
  }

  _changeName = (e) => {
    this.setState({name: e.target.value});
  }

  _changeAge = (e) => {
    this.setState({age: e.target.value});
  }

  _changeCountry = (e) => {
    this.setState({country: e.target.value});
  }

  _commitAutoSave = () => {
    Ajax.postJSON('/someAPI/json/autosave', {
      name: this.state.name,
      age: this.state.age,
      country: this.state.country
    });
  }

  render() {
    let {name, age, country} = this.state;
    return (
      <form>
        <input type="text" value={name} onChange={this._changeName} />
        <input type="text" value={age} onChange={this._changeAge} />
        <input type="text" value={country} onChange={this._changeCountry} />
      </form>
    );
  }
}

Böylece, bileşende bir statedeğişiklik olduğunda , verileri otomatik olarak kaydedecektir. Bunu uygulamanın başka yolları da var. componentDidUpdateBir işlem yapılması gerektiği zaman özellikle yararlıdır sonra DOM güncellenir ve güncelleme kuyruğu boşaltılır. Muhtemelen en çok karmaşık rendersve / stateveya DOM değişikliklerinde veya bir şeye kesinlikle ihtiyaç duyduğunuzda yararlıdır. son şey yürütülecek.

Yukarıdaki örnek oldukça basit, ancak muhtemelen asıl noktayı kanıtlıyor. Bir iyileştirme, otomatik kaydetmenin gerçekleştirebileceği süreyi sınırlamak olabilir (örneğin, maksimum her 10 saniyede bir) çünkü şu anda her tuş vuruşunda çalışacaktır.

Bunu göstermek için de bu keman için bir demo yaptım .


Daha fazla bilgi için resmi belgelere bakın :

componentDidUpdate()güncelleme gerçekleştikten hemen sonra çağrılır. Bu yöntem, ilk oluşturma için çağrılmaz.

Bunu, bileşen güncellendiğinde DOM üzerinde çalışmak için bir fırsat olarak kullanın. Bu aynı zamanda mevcut props ile önceki propsleri karşılaştırdığınız sürece ağ istekleri yapmak için iyi bir yerdir (örneğin, proplar değişmediyse bir ağ talebi gerekli olmayabilir).


Bence this.setState({...}, callback), callbackeşit _commitAutoSave, ne düşünüyorsun? Yani bence bu vaka componentDidUpdateyöntemi kullanabilir ama mecbur değil, haklı mıyım? fiddle
slideshowp2

1
Evet, bir geri arama kullanabilirsiniz, ancak arka arkaya çalıştırılan birden fazla setState varsa / varsa sorun daha karmaşık hale gelir.
Chris

Cevabınız için teşekkürler. Bu nedenle, componentDidUpdatebirden fazla setState'i çözmek için kullanılacak bir durum var ! Başka fikrin var mı?
slideshowp2

@novaline React-sound bileşeninde kullandıklarını görüyorum github.com/leoasis/react-sound/blob/master/src/index.js .. Neden kullandıklarından tam olarak emin değilim ama düşündüm Bakmanız için bağlantıyı paylaşırdım.
Sarah

3
Bu iyi bir örnek, ancak React belgelerinde önemli bir öneri eksik. "Bu, aynı zamanda, mevcut nesneleri önceki donanımlarla karşılaştırdığınız sürece ağ istekleri yapmak için iyi bir yerdir (örneğin, donanımlar değişmediyse bir ağ isteği gerekli olmayabilir)." reactjs.org/docs/react-component.html#componentdidupdate Benzer şekilde, CDU'da her arama yapıldığında çağrıyı koşullu mantık içinde sarmalamanız gerekir setState.
theUtherSide

5

Bazen yapıcıda veya componentDidMount'ta props'tan bir durum değeri ekleyebilirsiniz, props değiştiğinde ancak bileşen zaten bağlandığında setState'i çağırmanız gerekebilir, bu nedenle componentDidMount çalışmayacak ve yapıcı da olmayacaktır; bu özel durumda, props değiştiği için componentDidUpdate'i kullanabilirsiniz, componentDidUpdate'te setState'i yeni props ile çağırabilirsiniz.


2

componentDidUpdate()Highchart'ta kullandım .

İşte bu bileşenin basit bir örneği.

import React, { PropTypes, Component } from 'react';
window.Highcharts = require('highcharts');

export default class Chartline extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chart: ''
    };
  }

  public componentDidUpdate() {
    // console.log(this.props.candidate, 'this.props.candidate')
    if (this.props.category) {
      const category = this.props.category ? this.props.category : {};
      console.log('category', category);
      window.Highcharts.chart('jobcontainer_' + category._id, {
        title: {
          text: ''
        },
        plotOptions: {
          series: {
            cursor: 'pointer'
          }
        },
        chart: {
          defaultSeriesType: 'spline'
        },
        xAxis: {
          // categories: candidate.dateArr,
          categories: ['Day1', 'Day2', 'Day3', 'Day4', 'Day5', 'Day6', 'Day7'],
          showEmpty: true
        },
        labels: {
          style: {
            color: 'white',
            fontSize: '25px',
            fontFamily: 'SF UI Text'
          }
        },
        series: [
          {
            name: 'Low',
            color: '#9B260A',
            data: category.lowcount
          },
          {
            name: 'High',
            color: '#0E5AAB',
            data: category.highcount
          },
          {
            name: 'Average',
            color: '#12B499',
            data: category.averagecount
          }
        ]
      });
    }
  }
  public render() {
    const category = this.props.category ? this.props.category : {};
    console.log('render category', category);
    return <div id={'jobcontainer_' + category._id} style={{ maxWidth: '400px', height: '180px' }} />;
  }
}

2
componentDidUpdate(prevProps){ 

    if (this.state.authToken==null&&prevProps.authToken==null) {
      AccountKit.getCurrentAccessToken()
      .then(token => {
        if (token) {
          AccountKit.getCurrentAccount().then(account => {
            this.setState({
              authToken: token,
              loggedAccount: account
            });
          });
        } else {
          console.log("No user account logged");
        }
      })
      .catch(e => console.log("Failed to get current access token", e));

    }
}

1

Bu yaşam döngüsü yöntemi, güncelleme gerçekleşir gerçekleşmez çağrılır. ComponentDidUpdate () yönteminin en yaygın kullanım örneği, özellik veya durum değişikliklerine yanıt olarak DOM'u güncellemektir.

Bu yaşam döngüsünde setState () 'i çağırabilirsiniz, ancak önceki durumdan durum veya prop değişikliklerini kontrol etmek için onu bir koşula sarmanız gerekeceğini unutmayın. SetState () 'in yanlış kullanımı sonsuz döngüye neden olabilir. Bu yaşam döngüsü yönteminin tipik bir kullanım örneğini gösteren aşağıdaki örneğe bir göz atın.

componentDidUpdate(prevProps) {
 //Typical usage, don't forget to compare the props
 if (this.props.userName !== prevProps.userName) {
   this.fetchData(this.props.userName);
 }
}

Yukarıdaki örnekte, mevcut prop'ları önceki prop'larla karşılaştırdığımıza dikkat edin. Bu, sahne donanımında şu anda olduğundan bir değişiklik olup olmadığını kontrol etmek içindir. Bu durumda, props değişmediyse API çağrısı yapmaya gerek olmayacaktır.

Daha fazla bilgi için resmi belgelere bakın :


Durumda ne yapmalı this.fetchData is not a function?
tomrlh

tomrlh bu bir işlev çağrısı
Kashif

0

Durumdaki bir şey değiştiğinde ve bir yan etki çağırmanız gerektiğinde (api - alma, koyma, gönderme, silme isteği gibi). Yani araman gerekiyor componentDidUpdate()çünkücomponentDidMount() zaten aranıyor.

ComponentDidUpdate () 'de yan etkiyi çağırdıktan sonra, .pst dosyasındaki yanıt verilerine göre durumu yeni değere ayarlayabilirsiniz then((response) => this.setState({newValue: "here"})). Durumu yeni bir değere ayarlarken, componentDidUpdate () tekrar çağıracağından sonsuz döngüyü kontrol etmeniz prevPropsveya prevStateönlemeniz gerektiğinden emin olun .

En iyi uygulama için yan etki çağırılabilecek 2 yer vardır - componentDidMount () ve componentDidUpdate ()

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.