Kapan menggunakan metode React “componentDidUpdate”?


109

Saya menulis lusinan Reactfile, tidak pernah menggunakan componentDidUpdatemetode.

Apakah ada contoh umum kapan perlu menggunakan metode ini?

Saya ingin contoh dunia nyata, bukan demo sederhana.

Terima kasih atas jawabannya!



Kasus sederhana ketika Anda ingin menyetel status awal komponen saat dimuat.
Rajesh

@Rajesh Bisakah Anda menjelaskan atau memberi saya contoh? Terima kasih!
slideshowp2

1
Saya pikir kasus penggunaan yang paling umum adalah ketika Anda memiliki perpustakaan lain (jQuery, D3 ...) yang bekerja langsung di DOM, digabungkan bersama dengan React. Dalam skenario seperti itu, jika pustaka lain perlu melakukan transformasi DOM, Anda harus menggunakan componentDidUpdate untuk memastikan shadow DOM React telah di-flush ke DOM asli.
Jorge

1
Untuk menguraikan komentar @ Jorge: Saya pikir kasus yang paling umum adalah MEMBACA dari DOM asli setelah React diperbarui. Misalnya, saat Anda ingin mengetahui dimensi elemen DOM yang tepat, atau posisi elemen DOM di viewport. Misalnya untuk animasi atau transisi yang ingin Anda kelola untuk bereaksi. Saya pasti akan menyarankan agar tidak menggunakan jQuery untuk mengubah DOM setelah react telah dirender. Setelah react + library lain mengubah bagian DOM yang sama adalah ide yang buruk.
wintvelt

Jawaban:


89

Contoh sederhananya adalah aplikasi yang mengumpulkan data masukan dari pengguna dan kemudian menggunakan Ajax untuk mengunggah data tersebut ke database. Berikut adalah contoh yang disederhanakan (belum menjalankannya - mungkin memiliki kesalahan sintaks):

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

Jadi, setiap kali komponen mengalami stateperubahan, data akan disimpan secara otomatis. Ada cara lain untuk menerapkannya juga. Ini componentDidUpdatesangat berguna ketika operasi perlu terjadi setelah DOM diperbarui dan antrian pembaruan dikosongkan. Ini mungkin paling berguna pada perubahan kompleks rendersdan stateatau DOM atau ketika Anda membutuhkan sesuatu yang benar - benar hal terakhir untuk dieksekusi.

Contoh di atas agak sederhana, tetapi mungkin membuktikan maksudnya. Peningkatan dapat berupa membatasi berapa kali penyimpanan otomatis dapat dijalankan (mis. Maks setiap 10 detik) karena sekarang ini akan berjalan pada setiap penekanan tombol.

Saya membuat demo tentang biola ini juga untuk didemonstrasikan.


Untuk info lebih lanjut, lihat dokumen resmi :

componentDidUpdate()dipanggil segera setelah pembaruan terjadi. Metode ini tidak dipanggil untuk render awal.

Gunakan ini sebagai kesempatan untuk mengoperasikan DOM ketika komponen telah diperbarui. Ini juga merupakan tempat yang baik untuk melakukan permintaan jaringan selama Anda membandingkan props saat ini dengan props sebelumnya (misalnya, permintaan jaringan mungkin tidak diperlukan jika props tidak berubah).


Saya pikir this.setState({...}, callback), callbacksama _commitAutoSave, bagaimana menurut Anda? Jadi, saya rasa kasus ini bisa menggunakan componentDidUpdatemetode, tapi tidak harus, benar kan? biola
slideshowp2

1
Ya, Anda dapat menggunakan callback, namun masalahnya menjadi lebih rumit ketika / jika ada beberapa setState yang dijalankan secara berurutan.
Chris

Terima kasih atas jawaban anda. Jadi, satu kasus untuk digunakan componentDidUpdateadalah menyelesaikan beberapa setStates! Ada ide lain?
slideshowp2

@novaline Saya melihat mereka menggunakannya di komponen react-sound github.com/leoasis/react-sound/blob/master/src/index.js .. Saya tidak begitu yakin mengapa mereka menggunakannya tetapi saya pikir saya akan membagikan tautan untuk Anda lihat.
Sarah

3
Ini adalah contoh yang bagus, tetapi tidak ada rekomendasi utama dari dokumen React. "Ini juga merupakan tempat yang baik untuk melakukan permintaan jaringan selama Anda membandingkan properti saat ini dengan properti sebelumnya (misalnya, permintaan jaringan mungkin tidak diperlukan jika properti belum berubah)." reactjs.org/docs/react-component.html#componentdidupdate Demikian pula, seseorang harus membungkus panggilan dalam logika bersyarat setiap kali memanggil setStatedalam CDU.
theUtherSide

5

Kadang-kadang Anda mungkin menambahkan nilai status dari props di konstruktor atau componentDidMount, Anda mungkin perlu memanggil setState ketika props berubah tetapi komponen sudah dipasang sehingga componentDidMount tidak akan dijalankan dan begitu pula konstruktor; dalam kasus khusus ini, Anda bisa menggunakan componentDidUpdate karena props telah berubah, Anda bisa memanggil setState di componentDidUpdate dengan props baru.


2

Saya telah digunakan componentDidUpdate()di highchart.

Berikut adalah contoh sederhana dari komponen ini.

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

Metode siklus hidup ini dipanggil segera setelah pembaruan terjadi. Kasus penggunaan paling umum untuk metode componentDidUpdate () adalah memperbarui DOM sebagai respons terhadap perubahan prop atau status.

Anda bisa memanggil setState () dalam siklus hidup ini, tetapi perlu diingat bahwa Anda perlu menggabungkannya dalam kondisi untuk memeriksa perubahan status atau prop dari status sebelumnya. Penggunaan setState () yang salah dapat menyebabkan pengulangan tak terbatas. Lihat contoh di bawah ini yang menunjukkan contoh penggunaan umum metode siklus hidup ini.

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

Perhatikan pada contoh di atas bahwa kami membandingkan props saat ini dengan props sebelumnya. Ini untuk memeriksa apakah telah terjadi perubahan pada props dari saat ini. Dalam kasus ini, tidak perlu melakukan panggilan API jika props tidak berubah.

Untuk info lebih lanjut, lihat dokumen resmi:


Apa yang harus dilakukan jika terjadi this.fetchData is not a function?
tomrlh

tomrlh itu adalah panggilan fungsi
Kashif

0

Ketika sesuatu dalam status telah berubah dan Anda perlu memanggil efek samping (seperti permintaan ke api - get, put, post, delete). Jadi Anda perlu menelepon componentDidUpdate()karena componentDidMount()sudah dipanggil.

Setelah memanggil efek samping di componentDidUpdate (), Anda bisa menyetel status ke nilai baru berdasarkan data respons di then((response) => this.setState({newValue: "here"})). Pastikan Anda perlu memeriksa prevPropsatau prevStatemenghindari loop tak terbatas karena ketika menyetel status ke nilai baru, componentDidUpdate () akan memanggil lagi.

Ada 2 tempat untuk memanggil efek samping untuk praktik terbaik - componentDidMount () dan componentDidUpdate ()

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.