Component
Component
adalah kelas dasar untuk komponen React yang didefinisikan sebagai JavaScript classes. Kelas komponen masih didukung oleh React, tetapi kami tidak merekomendasikan untuk menggunakannya di kode baru.
class Greeting extends Component {
render() {
return <h1>Halo, {this.props.name}!</h1>;
}
}
- Referensi
Component
context
props
refs
state
constructor(props)
componentDidCatch(error, info)
componentDidMount()
componentDidUpdate(prevProps, prevState, snapshot?)
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
forceUpdate(callback?)
getChildContext()
getSnapshotBeforeUpdate(prevProps, prevState)
render()
setState(nextState, callback?)
shouldComponentUpdate(nextProps, nextState, nextContext)
UNSAFE_componentWillMount()
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
UNSAFE_componentWillUpdate(nextProps, nextState)
static childContextTypes
static contextTypes
static contextType
static defaultProps
static propTypes
static getDerivedStateFromError(error)
static getDerivedStateFromProps(props, state)
- Penggunaan
- Alternatif
Referensi
Component
Untuk mendefinisikan sebuah komponen React sebagai sebuah kelas, extend kelas Component
bawaan dan definisikan method render
:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Halo, {this.props.name}!</h1>;
}
}
Hanya method render
yang diperlukan, method yang lain adalah opsional.
Lihat lebih banyak contoh di bawah
context
Context dari sebuah class component tersedia sebagai this.context
. Ini hanya tersedia jika Anda menentukan context yang mana yang ingin Anda terima menggunakan static contextType
(modern) atau static contextTypes
(deprecated).
Class component hanya bisa membaca satu context pada satu waktu.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}
props
props yang dioper ke sebuah class component tersedia sebagai this.props
.
class Greeting extends Component {
render() {
return <h1>Halo, {this.props.name}!</h1>;
}
}
<Greeting name="Taylor" />
refs
Memungkinkan Anda mengakses legacy string refs pada komponen ini.
state
State dari class component tersedia sebagai this.state
. Field state harus berupa objek. Jangan mengubah state secara langsung. Jika Anda ingin mengubah state, panggil setState
dengan state baru.
class Counter extends Component {
state = {
age: 42,
};
handleAgeChange = () => {
this.setState({
age: this.state.age + 1
});
};
render() {
return (
<>
<button onClick={this.handleAgeChange}>
Increment age
</button>
<p>You are {this.state.age}.</p>
</>
);
}
}
constructor(props)
Constructor dijalankan sebelum class component Anda dipasang (ditambahkan ke layar). Biasanya, sebuah constructor hanya digunakan untuk dua tujuan dalam React. Ini memungkinkan Anda mendeklarasikan state dan bind class methods Anda ke class instance:
class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}
Jika Anda menggunakan sintaksis JavaScript modern, constructors jarang diperlukan. Sebagai gantinya, Anda dapat menulis ulang kode di atas menggunakan public class field syntax yang didukung oleh browser modern dan alat seperti Babel:
class Counter extends Component {
state = { counter: 0 };
handleClick = () => {
// ...
}
Sebuah constructor sebaiknya tidak mengandung side effects atau subscriptions.
Parameter
props
: Props awal komponen.
Kembalian
constructor
seharusnya tidak mengembalikan apapun.
Catatan penting
-
Jangan menjalankan side effects atau subscriptions dalam constructor. Sebagai gantinya, gunakan
componentDidMount
untuk itu. -
Dalam sebuah constructor, Anda perlu memanggil
super(props)
sebelum pernyataan lainnya. Jika Anda tidak melakukannya,this.props
akan menjadiundefined
saat constructor berjalan, yang dapat membingungkan dan menyebabkan bug. -
Constructor adalah satu-satunya tempat di mana Anda dapat langsung mengisi nilai
this.state
. Pada semua metode lainnya, Anda perlu menggunakanthis.setState()
sebagai gantinya. Jangan memanggilsetState
di dalam constructor. -
Ketika Anda menggunakan pe-render-an di server, constructor juga akan dijalankan di server, diikuti oleh metode
render
. Namun, lifecycle methods seperticomponentDidMount
ataucomponentWillUnmount
tidak akan dijalankan di server. -
Ketika Strict Mode diaktifkan, React akan memanggil
constructor
dua kali dalam pengembangan kemudian membuang salah satu instances. Ini membantu Anda memperhatikan side effects yang tidak disengaja yang perlu dipindahkan dariconstructor
.
componentDidCatch(error, info)
Jika Anda mendefinisikan componentDidCatch
, React akan memanggilnya ketika beberapa komponen anak(termasuk anak-anak yang jauh) melempar sebuah kesalahan saat rendering. Hal ini memungkinkan Anda untuk mencatat kesalahan tersebut ke error reporting service di produksi.
Biasanya, digunakan bersama dengan static getDerivedStateFromError
yang memungkinkan Anda memperbarui state sebagai respons terhadap kesalahan dan menampilkan pesan kesalahan kepada pengguna. Komponen dengan metode-metode ini disebut sebagai error boundary.
Parameter
-
error
: Error yang dilempar. Pada praktiknya, biasanya akan berupa sebuah instance dariError
tetapi ini tidak dijamin karena JavaScript memungkinkan untukthrow
nilai apa pun, termasuk string atau bahkan null. -
info
: Objek yang berisi informasi tambahan tentang error. FieldcomponentStack
berisi jejak tumpukan(stack trace) dengan komponen yang melempar kesalahan, serta nama-nama dan lokasi sumber dari semua komponen induknya. Di produksi, nama komponennya akan di-minified. Jika Anda mengatur error reporting di produksi, Anda dapat mendekode jejak tumpukan(stack trace) komponen menggunakan sourcemaps dengan cara yang sama seperti yang Anda lakukan untuk jejak tumpukan(stack trace) kesalahan JavaScript biasa.
Kembalian
componentDidCatch
seharusnya tidak mengembalikan apapun.
Catatan penting
-
Di masa lalu, umumnya memanggil
setState
di dalamcomponentDidCatch
untuk memperbarui antarmuka pengguna(UI) dan menampilkan pesan kesalahan pengganti. Ini sudah ditinggalkan karena mendefinisikanstatic getDerivedStateFromError
. -
Build produksi dan pengembangan dari React sedikit berbeda dalam cara
componentDidCatch
menangani kesalahan. Pada pengembangan, kesalahan akan naik kewindow
, yang berartiwindow.onerror
atauwindow.addEventListener('error', callback)
akan menangkap kesalahan yang telah ditangkap olehcomponentDidCatch
. Pada produksi, sebaliknya, kesalahan tidak akan naik, yang berarti penangan kesalahan induk hanya akan menerima kesalahan yang tidak ditangkap secara eksplisit olehcomponentDidCatch
.
componentDidMount()
Jika Anda mendefinisikan metode componentDidMount
, React akan memanggilnya ketika komponen Anda ditambahkan*(mounted)* ke layar. Ini adalah tempat umum untuk memulai pengambilan data, menyiapkan subscriptions, atau memanipulasi DOM nodes.
Jika Anda mengimplementasikan componentDidMount
, biasanya Anda juga perlu mengimplementasikan lifecycle methods lainnya untuk menghindari bug. Sebagai contoh, jika componentDidMount
membaca sebuah state atau props, Anda juga harus mengimplementasikan componentDidUpdate
untuk menangani perubahan mereka, dan componentWillUnmount
untuk membersihkan apa pun yang dilakukan oleh componentDidMount
.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Parameter
componentDidMount
tidak mengambil parameter apa pun.
Kembalian
componentDidMount
seharusnya tidak mengembalikan apapun.
Catatan penting
-
Ketika Strict Mode aktif, di pengembangan React kan memanggil
componentDidMount
, kemudian segera memanggilcomponentWillUnmount
, dan kemudian memanggilcomponentDidMount
lagi. Ini membantu Anda melihai jika Anda lupa untuk mengimplementasikancomponentWillUnmount
atau jika logikanya tidak sepenuhnya “mencerminkan” apa yang dilakukan olehcomponentDidMount
. -
Meskipun Anda dapat langsung memanggil
setState
dicomponentDidMount
, sebaiknya hindari hal itu jika bisa. Ini akan memicu render-ing ekstra, tetapi itu akan terjadi sebelum browser memperbarui layar. Ini menjamin bahwa meskipunrender
akan dipanggil dua kali dalam kasus ini, pengguna tidak akan melihat state perantara. Gunakan pola ini dengan hati-hati karena sering menyebabkan masalah performa. Dalam kebanyakan kasus, Anda seharusnya dapat menetapkan state awal diconstructor
sebagai gantinya. Namun, dalam beberapa kasus seperti modal dan tooltip ketika Anda perlu mengukur sebuah DOM node sebelum me-render sesuatu yang bergantung pada ukuran atau posisinya.
componentDidUpdate(prevProps, prevState, snapshot?)
Jika Anda mendefinisikan metode componentDidUpdate
, React akan memanggilnya segera setelah komponen Anda di-render ulang dengan prop atau state yang diperbarui. Metode ini tidak dipanggil saat render awal.
Anda dapat menggunakannya untuk memanipulasi DOM setelah pembaruan. Ini juga tempat umum untuk melakukan permintaan jaringan selama Anda membandingkan prop saat ini dengan prop sebelumnya (misalnya, permintaan jaringan mungkin tidak diperlukan jika prop tidak berubah). Biasanya, Anda akan menggunakannya bersama dengan componentDidMount
dan componentWillUnmount
:
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Parameter
-
prevProps
: Props sebelum update. MembandingkanprevProps
kethis.props
untuk menentukan apa yang berubah. -
prevState
: State sebelum update. MembandingkanprevState
kethis.state
untuk menentukan apa yang berubah. -
snapshot
: Jika Anda mengimplementasikangetSnapshotBeforeUpdate
,snapshot
akan berisi nilai yang Anda kembalikan dari metode tersebut. Jika tidak, nilainya akanundefined
.
Kembalian
componentDidUpdate
seharusnya tidak mengembalikan apapun.
Catatan penting
-
componentDidUpdate
tidak akan dipanggil jikashouldComponentUpdate
didefinisikan dan mengembalikanfalse
. -
Logika di dalam
componentDidUpdate
biasanya harus dibungkus dalam kondisi yang membandingkanthis.props
denganprevProps
, danthis.state
denganprevState
. Jika tidak, ada risiko terjadi perulangan tak terbatas. -
Meskipun Anda dapat memanggil
setState
langsung di dalamcomponentDidUpdate
, sebaiknya hindari hal itu jika memungkinkan. Ini akan memicu render tambahan, tetapi akan terjadi sebelum browser memperbarui tampilan. Ini menjamin bahwa meskipunrender
akan dipanggil dua kali dalam kasus ini, pengguna tidak akan melihat intermediate state. Pola ini sering menyebabkan isu performance, tetapi mungkin diperlukan untuk kasus-kasus langka seperti modal dan tooltip ketika Anda perlu mengukur node DOM sebelum me-render sesuatu yang bergantung pada ukuran atau posisinya.
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
Jika Anda mendefinisikan metode componentWillUnmount
, React akan memanggilnya sebelum komponen Anda dihapus (unmounted) dari layar. Ini adalah tempat umum untuk membatalkan pengambilan data atau menghapus langganan.
Logika di dalam componentWillUnmount
harus “mencerminkan” logika di dalam componentDidMount
. Sebagai contoh, jika componentDidMount
mempersiapkan langganan, componentWillUnmount
harus membersihkan langganan itu. Jika logika pembersihan di componentWillUnmount
membaca beberapa props atau state, Anda biasanya juga perlu menerapkan componentDidUpdate
untuk membersihkan sumber daya (seperti langganan) yang sesuai dengan props dan state lama.
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}
Parameter
componentWillUnmount
tidak mengambil parameter apapun.
Kembalian
componentWillUnmount
seharusnya tidak mengembalikan apapun.
Catatan penting
- Ketika Strict Mode aktif, pada development React akan memanggil
componentDidMount
, kemudian segera memanggilcomponentWillUnmount
, dan kemudian memanggilcomponentDidMount
lagi. Ini membantu Anda memperhatikan jika Anda lupa menerapkancomponentWillUnmount
atau jika logikanya tidak sepenuhnya “mencerminkan” apa yangcomponentDidMount
lakukan.
forceUpdate(callback?)
Memaksa komponen untuk me-render ulang.
Biasanya, ini tidak perlu. Jika metode render
komponen Anda hanya baca(only reads) dari this.props
, this.state
, atau this.context
, akan me-render ulang otomatis ketika Anda memanggil setState
di dalam komponen Anda atau salah satu dari parent. Namun, Jika metode render
komponen Anda membaca secara langsung dari sumber data eksternal, Anda harus memberi tahu React untuk memperbarui antarmuka pengguna saat sumber data itu berubah. Itulah yang forceUpdate
memungkinkan Anda melakukannya.
Cobalah untuk menghindari semua penggunaan forceUpdate
dan hanya membaca dari this.props
dan this.state
pada render
.
Parameter
- optional
callback
Jika ditentukan, React akan memanggilcallback
yang Anda berikan setelah pembaruan dilakukan.
Kembalian
forceUpdate
tidak mengembalikan apapun.
Catatan penting
- Jika Anda memanggil
forceUpdate
, React akan me-render ulang tanpa memanggilshouldComponentUpdate
.
getChildContext()
Memungkinkan Anda menentukan nilai untuk legacy context yang disediakan oleh komponen ini.
getSnapshotBeforeUpdate(prevProps, prevState)
Jika Anda mengimplementasikan getSnapshotBeforeUpdate
, React akan segera memanggilnya sebelum React memperbarui DOM. Ini memungkinkan komponen Anda untuk menangkap beberapa informasi dari DOM (e.g. posisi scroll) sebelum berpotensi diubah. Nilai apa pun yang dikembalikan oleh lifecycle method ini akan diteruskan sebagai parameter ke componentDidUpdate
.
Misalnya, Anda dapat menggunakannya di UI seperti utas obrolan yang perlu mempertahankan posisi scroll-nya selama pembaruan:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Apakah kita menambahkan item baru ke dalam list?
// Tangkap posisi scroll supaya kita dapat mengatur scroll nanti.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// Apabila kita memiliki nilai snapshot, kita baru saja menambahkan item baru.
// Atur scroll supaya item-item baru ini tidak mendorong item-item lama ke luar tampilan.
// (snapshot adalah nilai yang dikembalikan dari getSnapshotBeforeUpdate)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
Pada contoh di atas, penting untuk membaca properti scrollHeight
secara langsung di getSnapshotBeforeUpdate
. Tidak aman untuk membacanya di render
, UNSAFE_componentWillReceiveProps
, atau UNSAFE_componentWillUpdate
karena ada potensi jeda waktu antara pemanggilan metode ini dan React memperbarui DOM.
Parameter
-
prevProps
: Props sebelum pembaharuan. MembandingkanprevProps
kethis.props
untuk menentukan apa yang berubah. -
prevState
: State sebelum pembaharuan. MembandingkanprevState
kethis.state
untuk menentukan apa yang berubah.
Kembalian
Anda harus mengembalikan nilai snapshot dari jenis apa pun yang Anda inginkan, atau null
. Nilai yang Anda kembalikan akan diteruskan sebagai argumen ketiga pada componentDidUpdate
.
Catatan penting
getSnapshotBeforeUpdate
tidak akan dipanggil jikashouldComponentUpdate
didefinisikan dan mengembalikanfalse
.
render()
Metode render
adalah satu-satunya metode yang diperlukan dalam class component.
Metode render
harus menentukan apa yang ingin Anda tampilkan di layar, misalnya:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
React dapat memanggil render
kapan saja, jadi Anda tidak boleh berasumsi bahwa itu berjalan pada waktu tertentu. Biasanya, metode render
harus mengembalikan sebagian dari JSX, tetapi beberapa jenis return lainnya (seperti strings) didukung. Untuk menghitung JSX yang dikembalikan, metode render
dapat membacathis.props
, this.state
, dan this.context
.
Anda harus menulis metode render
sebagai pure function, artinya ia harus mengembalikan hasil yang sama jika props, state, dan context-nya sama. Itu juga tidak boleh mengandung side effects (seperti menyiapkan subscriptions) atau interaksi dengan API peramban. Side effects harus terjadi baik dalam event handlers atau metode seperti componentDidMount
.
Parameter
-
prevProps
: Props sebelum pembaruan. BandingkanprevProps
kethis.props
untuk menentukan apa yang berubah. -
prevState
: State sebelum pembaruan. BandingkanprevState
kethis.state
untuk menentukan apa yang berubah.
Kembalian
render
dapat mengembalikan node React apa pun yang valid. Ini termasuk elemen-elemen React seperti <div />
, strings, numbers, portals, nodes kosong (null
, undefined
, true
, dan false
), dan arrays dari React nodes.
Catatan penting
-
render
harus ditulis sebagai pure function dari props, state, dan context. Seharusnya tidak memiliki side effects. -
render
tidak akan dipanggil jikashouldComponentUpdate
didefinisikan dan mengembalikanfalse
. -
Ketika Strict Mode aktif, React akan memanggil
render
dua kali dalam development dan kemudian membuang salah satu hasilnya. Ini membantu Anda melihat efek samping yang tidak disengaja yang perlu dipindahkan dari metoderender
. -
Tidak ada korespondensi satu-satu antara panggilan
render
dan panggilancomponentDidMount
atau panggilancomponentDidUpdate
. Beberapa hasil panggilanrender
mungkin dibuang oleh React jika bermanfaat.
setState(nextState, callback?)
Memanggil setState
untuk mengupdate state dari komponen React Anda.
class Form extends Component {
state = {
name: 'Taylor',
};
handleNameChange = (e) => {
const newName = e.target.value;
this.setState({
name: newName
});
}
render() {
return (
<>
<input value={this.state.name} onChange={this.handleNameChange} />
<p>Hello, {this.state.name}.</p>
</>
);
}
}
setState
mengantrekan perubahan ke state komponen. Ini memberi tahu React bahwa komponen ini dan turunannya perlu di-render ulang dengan state baru. Ini adalah cara utama Anda memperbarui antarmuka pengguna sebagai respons terhadap interaksi.
Anda juga dapat meneruskan fungsi ke setState
. Ini memungkinkan Anda memperbarui state berdasarkan state sebelumnya:
handleIncreaseAge = () => {
this.setState(prevState => {
return {
age: prevState.age + 1
};
});
}
Anda tidak harus melakukan ini, tetapi akan berguna jika Anda ingin memperbarui state beberapa kali selama event yang sama.
Parameter
-
nextState
: Baik objek atau fungsi.- Jika Anda meneruskan objek sebagai
nextState
, objek tersebut akan digabungkan secara dangkal ke dalamthis.state
. - Jika Anda meneruskan fungsi sebagai
nextState
, fungsi tersebut akan diperlakukan sebagai updater function. Itu harus murni, harus mengambilstate
danprops
yang tertunda sebagai argumen, dan harus mengembalikan objek untuk digabungkan secara dangkal ke dalamthis.state
. React akan menempatkan fungsi pembaru Anda dalam antrean dan merender ulang komponen Anda. Selama render berikutnya, React akan menghitung state selanjutnya dengan menerapkan semua pembaruan yang antri ke state sebelumnya.
- Jika Anda meneruskan objek sebagai
-
opsional
callback
: Jika ditentukan, React akan memanggilcallback
yang Anda berikan setelah pembaruan dilakukan.
Kembalian
setState
tidak mengembalikan apapun.
Catatan penting
-
Pikirkan
setState
sebagai permintaan daripada perintah langsung untuk memperbarui komponen. Ketika beberapa komponen memperbarui state-nya sebagai respons terhadap suatu event, React akan mengelompokkan pembaruannya dan merendernya kembali bersama-sama dalam satu lintasan di akhir event. Dalam kasus yang jarang terjadi saat Anda perlu memaksa pembaruan state tertentu untuk diterapkan secara sinkron, Anda dapat menggabungkannya dalamflushSync
, tetapi ini dapat mengganggu kinerja. -
setState
tidak segera memperbaruithis.state
. Hal ini membuat pembacaanthis.state
tepat setelah memanggilsetState
menjadi potensial jebakan. Sebagai gantinya, gunakancomponentDidUpdate
atau argumen setStatecallback
, yang keduanya dijamin akan aktif setelah pembaruan diterapkan. Jika Anda perlu menyetel state berdasarkan state sebelumnya, Anda dapat meneruskan fungsi kenextState
seperti yang dijelaskan di atas.
shouldComponentUpdate(nextProps, nextState, nextContext)
Jika Anda mendefinisikan shouldComponentUpdate
, React akan memanggilnya untuk menentukan apakah render ulang dapat dilewati.
Jika Anda yakin ingin menulisnya dengan tangan, Anda dapat membandingkan this.props
dengan nextProps
dan this.state
dengan nextState
dan mengembalikan false
untuk memberi tahu React bahwa pembaruan dapat dilewati.
class Rectangle extends Component {
state = {
isHovered: false
};
shouldComponentUpdate(nextProps, nextState) {
if (
nextProps.position.x === this.props.position.x &&
nextProps.position.y === this.props.position.y &&
nextProps.size.width === this.props.size.width &&
nextProps.size.height === this.props.size.height &&
nextState.isHovered === this.state.isHovered
) {
// Tidak ada yang berubah, jadi tidak perlu render ulang
return false;
}
return true;
}
// ...
}
React memanggil shouldComponentUpdate
sebelum render-ing ketika props baru atau state sedang diterima. Default true
. Metode ini tidak dipanggil untuk render awal atau saat forceUpdate
digunakan.
Parameter
nextProps
: Props berikutnya yang akan dirender oleh komponen. BandingkannextProps
denganthis.props
untuk menentukan apa yang berubah.nextState
: State berikutnya yang akan di-render oleh komponen. BandingkannextState
denganthis.state
untuk menentukan apa yang berubah.nextContext
: Konteks berikutnya yang akan di-render oleh komponen. BandingkannextContext
denganthis.context
untuk menentukan apa yang berubah. Hanya tersedia jika Anda menetapkanstatic contextType
(modern) ataustatic contextTypes
(legacy).
Kembalian
Mengembalikan true
jika Anda ingin komponen di-render ulang. Itu merupakan perilaku default.
Mengembalikan false
untuk memberitahu React bahwa render ulang dapat dilewati.
Catatan penting
-
Metode ini hanya ada sebagai pengoptimalan kinerja. Jika komponen Anda rusak tanpanya, perbaiki terlebih dahulu.
-
Pertimbangkan untuk menggunakan
PureComponent
daripada menulisshouldComponentUpdate
secara manual.PureComponent
secara dangkal membandingkan props dan state, dan mengurangi kemungkinan Anda melewati pembaruan yang diperlukan. -
Kami tidak menyarankan melakukan pemeriksaan kesetaraan mendalam atau menggunakan
JSON.stringify
dishouldComponentUpdate
. Itu membuat kinerja tidak dapat diprediksi dan bergantung pada struktur data setiap prop dan state. Dalam kasus terbaik, Anda berisiko memperkenalkan henti selama beberapa detik pada aplikasi Anda, dan dalam kasus terburuk Anda berisiko membuatnya crash. -
Mengembalikan
false
tidak mencegah komponen turunan dari render-ing ulang ketika state mereka berubah. -
Mengembalikan
false
tidak menjamin bahwa komponen tidak akan di-render ulang. React akan menggunakan nilai yang dikembalikan sebagai petunjuk tetapi mungkin masih memilih untuk me-render ulang komponen Anda jika masuk akal untuk dilakukan karena alasan lain.
UNSAFE_componentWillMount()
Jika Anda mendefinisikan UNSAFE_componentWillMount
, React akan memanggilnya segera setelah constructor
. Itu hanya ada karena alasan historis dan tidak boleh digunakan dalam kode baru apa pun. Sebagai gantinya, gunakan salah satu alternatif:
- Untuk menginisialisasi state, deklarasikan
state
sebagai bidang kelas atau setelthis.state
di dalamkonstruktor
. - Jika Anda perlu menjalankan efek samping atau menyiapkan langganan, pindahkan logika tersebut ke
componentDidMount
sebagai gantinya.
Lihat contoh migrasi dari unsafe lifecycles.
Parameter
UNSAFE_componentWillMount
tidak menggunakan parameter apa pun.
Kembalian
UNSAFE_componentWillMount
seharusnya tidak mengembalikan apa pun.
Catatan penting
-
UNSAFE_componentWillMount
tidak akan dipanggil jika komponen mengimplementasikanstatic getDerivedStateFromProps
ataugetSnapshotBeforeUpdate
. -
Terlepas dari namanya,
UNSAFE_componentWillMount
tidak menjamin bahwa komponen akan dipasang jika aplikasi Anda menggunakan fitur React modern sepertiSuspense
. Jika upaya render ditangguhkan (misalnya, karena kode untuk beberapa komponen anak belum dimuat), React akan membuang pohon yang sedang berjalan dan mencoba membangun komponen dari awal selama upaya berikutnya. Inilah mengapa metode ini “tidak aman”. Kode yang bergantung pada pemasangan (seperti menambahkan langganan) harus masuk kecomponentDidMount
. -
UNSAFE_componentWillMount
adalah satu-satunya metode siklus hidup yang berjalan selama server rendering. Untuk semua tujuan praktis, ini identik denganconstructor
, sehingga Anda harus menggunakankonstruktor
untuk jenis logika ini.
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
Jika Anda mendefinisikan UNSAFE_componentWillReceiveProps
, React akan memanggilnya ketika komponen menerima props baru. Itu hanya ada karena alasan historis dan tidak boleh digunakan dalam kode baru apa pun. Sebagai gantinya, gunakan salah satu alternatif:
- Jika Anda perlu menjalankan efek samping (misalnya, mengambil data, menjalankan animasi, atau menginisialisasi ulang langganan) sebagai respons terhadap perubahan prop, pindahkan logika tersebut ke
componentDidUpdate
sebagai gantinya. - Jika Anda perlu menghindari komputasi ulang beberapa data hanya saat prop berubah, gunakan memoization helper sebagai gantinya.
- Jika Anda perlu “mereset” beberapa state saat prop berubah, pertimbangkan untuk membuat komponen fully controlled atau fully uncontrolled with a key sebagai gantinya.
- Jika Anda perlu “menyesuaikan” beberapa status saat prop berubah, periksa apakah Anda dapat menghitung semua informasi yang diperlukan hanya dari prop selama render-ing. Jika tidak bisa, gunakan
static getDerivedStateFromProps
sebagai gantinya.
Lihat contoh migrasi dari unsafe lifecycles.
Parameter
nextProps
: Props berikutnya yang akan diterima komponen dari komponen induknya. BandingkannextProps
denganthis.props
untuk menentukan apa yang berubah.nextContext
: Props berikutnya yang akan diterima komponen dari penyedia terdekat. BandingkannextContext
denganthis.context
untuk menentukan apa yang berubah. Hanya tersedia jika Anda menetapkanstatic contextType
(modern) ataustatic contextTypes
(legacy).
Kembalian
UNSAFE_componentWillReceiveProps
seharusnya tidak mengembalikan apa pun.
Catatan penting
-
UNSAFE_componentWillReceiveProps
tidak akan dipanggil jika komponen mengimplementasikanstatic getDerivedStateFromProps
ataugetSnapshotBeforeUpdate
. -
Terlepas dari namanya,
UNSAFE_componentWillReceiveProps
tidak menjamin bahwa komponen akan menerima props tersebut jika aplikasi Anda menggunakan fitur React modern sepertiSuspense
. Jika upaya render ditangguhkan (misalnya , karena kode untuk beberapa komponen anak belum dimuat), React akan membuang pohon yang sedang dalam proses dan mencoba membangun komponen dari awal selama upaya berikutnya. Pada saat percobaan render berikutnya, props mungkin berbeda. Inilah mengapa metode ini “tidak aman”. Kode yang harus dijalankan hanya untuk pembaruan yang dilakukan (seperti menyetel ulang langganan) harus masuk kecomponentDidUpdate
. -
UNSAFE_componentWillReceiveProps
tidak berarti bahwa komponen telah menerima props yang berbeda dari sebelumnya. Anda perlu membandingkannextProps
danthis.props
sendiri untuk memeriksa apakah ada yang berubah. -
React tidak memanggil
UNSAFE_componentWillReceiveProps
dengan props awal selama mounting. Itu hanya memanggil metode ini jika beberapa props komponen akan diperbarui. Misalnya, memanggilsetState
biasanya tidak memicuUNSAFE_componentWillReceiveProps
di dalam komponen yang sama.
UNSAFE_componentWillUpdate(nextProps, nextState)
Jika Anda mendefinisikan UNSAFE_componentWillUpdate
, React akan memanggilnya sebelum me-render dengan props atau state baru. Itu hanya ada karena alasan historis dan tidak boleh digunakan dalam kode baru apa pun. Sebagai gantinya, gunakan salah satu alternatif:
- Jika Anda perlu menjalankan efek samping (misalnya, mengambil data, menjalankan animasi, atau menginisialisasi ulang langganan) sebagai respons terhadap perubahan prop atau state, pindahkan logika tersebut ke
componentDidUpdate
sebagai gantinya. - Jika Anda perlu membaca beberapa informasi dari DOM (misalnya, untuk menyimpan posisi gulir saat ini) sehingga Anda dapat menggunakannya di
componentDidUpdate
nanti, baca di dalamgetSnapshotBeforeUpdate
sebagai gantinya.
Lihat contoh migrasi dari unsafe lifecycles.
Parameter
nextProps
: Props berikutnya yang akan di-render oleh komponen. BandingkannextProps
denganthis.props
untuk menentukan apa yang berubah.nextState
: State selanjutnya yang akan di-render oleh komponen. BandingkannextState
denganthis.state
untuk menentukan apa yang berubah.
Kembalian
UNSAFE_componentWillUpdate
seharusnya tidak mengembalikan apa pun.
Catatan penting
-
UNSAFE_componentWillUpdate
tidak akan dipanggil jikashouldComponentUpdate
ditentukan dan mengembalikanfalse
. -
UNSAFE_componentWillUpdate
tidak akan dipanggil jika komponen mengimplementasikanstatic getDerivedStateFromProps
ataugetSnapshotBeforeUpdate
. -
Tidak didukung untuk memanggil
setState
(atau metode apa pun yang menyebabkansetState
dipanggil, seperti dispatching Redux action) selamacomponentWillUpdate
. -
Terlepas dari namanya,
UNSAFE_componentWillUpdate
tidak menjamin bahwa komponen akan diupdate jika aplikasi Anda menggunakan fitur React modern sepertiSuspense
. Jika upaya render ditangguhkan (misalnya, karena kode untuk beberapa komponen anak belum dimuat), React akan membuang pohon yang sedang berjalan dan mencoba membangun komponen dari awal selama upaya berikutnya. Pada saat upaya render berikutnya, props dan state mungkin berbeda. Inilah mengapa metode ini “tidak aman”. Kode yang harus dijalankan hanya untuk pembaruan yang dilakukan (seperti menyetel ulang langganan) harus masuk kecomponentDidUpdate
. -
UNSAFE_componentWillUpdate
tidak berarti bahwa komponen telah menerima props atau state yang berbeda dari sebelumnya. Anda perlu membandingkannextProps
denganthis.props
dannextState
denganthis.state
sendiri untuk memeriksa apakah ada yang berubah. -
React tidak memanggil
UNSAFE_componentWillUpdate
dengan props awal dan state selama pemasangan.
static childContextTypes
Memungkinkan Anda menentukan legacy context mana yang disediakan oleh komponen ini.
static contextTypes
Memungkinkan Anda menentukan legacy context yang dikonsumsi oleh komponen ini.
static contextType
Jika Anda ingin membaca this.context
dari class component Anda, Anda harus menentukan context mana yang perlu dibaca. Context yang Anda tentukan sebagai static contextType
harus berupa nilai yang dibuat sebelumnya oleh createContext
.
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}
static defaultProps
Anda dapat mendefinisikan static defaultProps
untuk mengatur props bawaan untuk class. Mereka akan digunakan untuk undefined
dan props yang hilang, tetapi tidak untuk props null
.
Sebagai contoh, di sini adalah bagaimana Anda mendefinisikan bahwa prop color
harus default ke 'blue'
:
class Button extends Component {
static defaultProps = {
color: 'blue'
};
render() {
return <button className={this.props.color}>click me</button>;
}
}
Jika prop color
tidak disediakan atau undefined
, maka akan disetel secara default ke 'blue'
:
<>
{/* this.props.color is "blue" */}
<Button />
{/* this.props.color is "blue" */}
<Button color={undefined} />
{/* this.props.color is null */}
<Button color={null} />
{/* this.props.color is "red" */}
<Button color="red" />
</>
static propTypes
Anda dapat mendefinisikan static propTypes
bersama dengan pustaka prop-types
untuk mendeklarasikan jenis props yang diterima oleh komponen Anda. Jenis ini akan diperiksa selama render-ing dan hanya dalam pengembangan.
import PropTypes from 'prop-types';
class Greeting extends React.Component {
static propTypes = {
name: PropTypes.string
};
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
static getDerivedStateFromError(error)
Jika Anda mendefinisikan static getDerivedStateFromError
, React akan memanggilnya ketika komponen anak (termasuk anak jauh) melemparkan kesalahan selama render-ing. Ini memungkinkan Anda menampilkan pesan kesalahan alih-alih menghapus UI.
Biasanya, ini digunakan bersama dengan componentDidCatch
yang memungkinkan Anda mengirim laporan kesalahan ke beberapa layanan analitik. Komponen dengan metode ini disebut error boundary.
Parameter
error
: Kesalahan yang dilemparkan. Dalam prakteknya, biasanya akan menjadi instance dariError
tetapi ini tidak dijamin karena JavaScript memungkinkan untukthrow
nilai apa saja, termasuk strings atau bahkannull
.
Kembalian
static getDerivedStateFromError
harus mengembalikan state yang memberi tahu komponen untuk menampilkan pesan kesalahan.
Catatan penting
static getDerivedStateFromError
harus berupa pure function. Jika Anda ingin melakukan efek samping (misalnya, untuk memanggil layanan analitik), Anda juga perlu mengimplementasikancomponentDidCatch
.
static getDerivedStateFromProps(props, state)
Jika Anda mendefinisikan static getDerivedStateFromProps
, React akan memanggilnya tepat sebelum memanggil render
, baik pada pemasangan awal maupun pembaruan berikutnya. Itu harus mengembalikan objek untuk memperbarui state, atau null
untuk tidak memperbarui apa pun.
Metode ini ada untuk kasus penggunaan yang jarang di mana states tergantung pada perubahan props dari waktu ke waktu. Misalnya, komponen Form
ini menyetel ulang state email
saat prop userID
berubah:
class Form extends Component {
state = {
email: this.props.defaultEmail,
prevUserID: this.props.userID
};
static getDerivedStateFromProps(props, state) {
// Setiap kali user saat ini berubah,
// Setel ulang bagian state mana pun yang terkait ke user itu.
// Dalam contoh simpel ini, hanya ada email.
if (props.userID !== state.prevUserID) {
return {
prevUserID: props.userID,
email: props.defaultEmail
};
}
return null;
}
// ...
}
Perhatikan bahwa pola ini mengharuskan Anda mempertahankan nilai prop sebelumnya (seperti userID
) dalam state (seperti prevUserID
).
Parameter
props
: Props berikutnya yang akan di-render oleh komponen.state
: State berikutnya yang akan di-render oleh komponen.
Kembalian
static getDerivedStateFromProps
mengembalikan objek untuk memperbarui state, atau null
untuk tidak memperbarui apa pun.
Catatan penting
-
Metode ini diaktifkan pada setiap render, apa pun penyebabnya. hal ini berbeda dengan
UNSAFE_componentWillReceiveProps
, yang hanya aktif bila induk menyebabkan render ulang dan bukan sebagai akibat darisetState
lokal. -
Metode ini tidak memiliki akses ke instance komponen. Jika mau, Anda bisa menggunakan kembali beberapa kode antara
static getDerivedStateFromProps
dan metode kelas lainnya dengan mengekstraksi fungsi murni dari props komponen dan state di luar definisi kelas.
Penggunaan
Mendefinisikan class component
Untuk mendefinisikan komponen React sebagai sebuah class, extend Component
class bawaan dan definisikan method render
:
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
React akan memanggil metode render
Anda kapan pun diperlukan untuk mencari tahu apa yang akan ditampilkan di layar. Biasanya, Anda akan mengembalikan beberapa JSX darinya. Metode render
Anda harus berupa pure function: yang seharusnya hanya menghitung JSX.
Mirip dengan function components, sebuah class component dapat menerima informasi dengan props dari komponen induknya. Namun, sintaks untuk membaca props berbeda. Misalnya, jika komponen induk me-render <Greeting name="Taylor" />
, maka Anda dapat membaca prop name
dari this.props
, seperti this.props.name
:
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Perhatikan bahwa Hooks (fungsi yang dimulai dengan use
, seperti useState
) tidak didukung di dalam class components.
Menambahkan state pada class component
Untuk menambahkan state ke dalam sebuah kelas, menetapkan objek ke properti yang disebut state
. Untuk mengupdate state, panggil this.setState
.
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = () => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
Menambahkan lifecycle methods ke class component
Ada beberapa metode khusus yang dapat Anda tentukan di kelas Anda.
Jika Anda mendefinisikan metode componentDidMount
, React akan memanggilnya ketika komponen Anda ditambahkan (mounted) ke layar. React akan memanggil componentDidUpdate
setelah komponen Anda di-render ulang karena perubahan props atau state. React akan memanggil componentWillUnmount
setelah komponen Anda dihapus (unmount) dari layar.
Jika Anda mengimplementasikan componentDidMount
, biasanya Anda perlu mengimplementasikan ketiga lifecycles untuk menghindari bug. Misalnya, jika componentDidMount
membaca beberapa state atau props, Anda juga harus mengimplementasikan componentDidUpdate
untuk menangani perubahannya, dan componentWillUnmount
untuk membersihkan apa pun yang dilakukan componentDidMount
.
Misalnya, komponen ChatRoom
ini menjaga koneksi obrolan tetap tersinkronisasi dengan props dan state:
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
Perhatikan bahwa dalam pengembangan saat Strict Mode aktif, React akan memanggil componentDidMount
, segera memanggil componentWillUnmount
, lalu memanggil componentDidMount
lagi. Ini membantu Anda menyadari jika Anda lupa mengimplementasikan componentWillUnmount
atau jika logikanya tidak sepenuhnya “mencerminkan” apa yang dilakukan componentDidMount
.
Catching rendering errors with an error boundary
Secara default, jika aplikasi Anda menampilkan kesalahan selama render-ing, React akan menghapus UI-nya dari layar. Untuk mencegah hal ini, Anda dapat menggabungkan sebagian UI ke dalam error boundary. Error Boundary adalah komponen khusus yang memungkinkan Anda menampilkan beberapa UI cadangan, bukan bagian yang mengalami kesalahan misalnya, pesan kesalahan.
Untuk mengimplementasikan komponen batas kesalahan (error boundary), Anda perlu menyediakan static getDerivedStateFromError
yang memungkinkan Anda memperbarui state sebagai respons terhadap kesalahan dan menampilkan pesan kesalahan kepada pengguna. Anda juga dapat secara opsional mengimplementasikan componentDidCatch
untuk menambahkan beberapa logika tambahan, misalnya, untuk mencatat kesalahan ke layanan analitik.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Perbarui state sehingga render selanjutnya menunjukkan UI fallback.
return { hasError: true };
}
componentDidCatch(error, info) {
// Contoh "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// Anda dapat me-render UI fallback apa pun.
return this.props.fallback;
}
return this.props.children;
}
}
Kemudian Anda dapat membungkus bagian dari pohon komponen Anda dengannya:
<ErrorBoundary fallback={<p>Something went wrong</p>}>
<Profile />
</ErrorBoundary>
Jika Profile
atau komponen anaknya mengalami kesalahan, ErrorBoundary
akan “menangkap” kesalahan tersebut, menampilkan UI cadangan dengan pesan kesalahan yang telah Anda sediakan, dan mengirim laporan kesalahan produksi ke layanan pelaporan kesalahan Anda.
Anda tidak perlu melibatkan setiap komponen ke dalam batas kesalahan (error boundary) yang terpisah. Saat Anda mempertimbangkan granularitas dari batas kesalahan, pertimbangkan di mana tepatnya menampilkan pesan kesalahan. Sebagai contoh, dalam aplikasi pesan, masuk akal untuk menempatkan batas kesalahan di sekitar daftar percakapan. Juga masuk akal untuk menempatkannya di sekitar setiap pesan individu. Namun, tidak masuk akal untuk menempatkan batasan di sekitar setiap avatar.
Alternatif
Migrasi komponen sederhana dari class ke sebuah function
Biasanya, Anda akan mendefinisikan komponen sebagai functions
.
Sebagai contoh, asumsikan Anda sedang mengonversi komponen kelas Greeting
ini menjadi sebuah fungsi:
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Tentukan sebuah fungsi yang disebut Greeting
. Di sinilah Anda akan memindahkan tubuh fungsi render
Anda.
function Greeting() {
// ... pindahkan kode dari `render method` di sini ...
}
Sebagai pengganti this.props.name
, definisikan prop name
menggunakan sintaks destructuring dan gunakan secara langsung:
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
Berikut contoh lengkapnya:
function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Migrasi komponen dengan state
dari kelas ke fungsi
Asumsikan Anda sedang mengonversi komponen kelas Counter
ini menjadi sebuah fungsi.
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = (e) => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
Mulai dengan mendeklarasikan sebuah fungsi dengan variabel state yang diperlukan:
import { useState } from 'react';
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
// ...
Selanjutnya, konversi event handlers
:
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
function handleNameChange(e) {
setName(e.target.value);
}
function handleAgeChange() {
setAge(age + 1);
}
// ...
Terakhir, gantikan semua referensi yang dimulai dengan this
dengan variabel dan fungsi yang Anda definisikan di komponen Anda. Misalnya, gantikan this.state.age
dengan age
, dan gantikan this.handleNameChange
dengan handleNameChange
.
Berikut adalah komponen yang telah sepenuhnya dikonversi:
import { useState } from 'react'; export default function Counter() { const [name, setName] = useState('Taylor'); const [age, setAge] = useState(42); function handleNameChange(e) { setName(e.target.value); } function handleAgeChange() { setAge(age + 1); } return ( <> <input value={name} onChange={handleNameChange} /> <button onClick={handleAgeChange}> Increment age </button> <p>Hello, {name}. You are {age}.</p> </> ) }
Migrasi sebuah komponen dengan lifecycle methods dari kelas ke fungsi
Asumsikan Anda sedang mengonversi komponen kelas ChatRoom
ini dengan lifecycle methods ke sebuah fungsi:
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
Pertama, verifikasi bahwa metode componentWillUnmount
Anda melakukan kebalikan dari componentDidMount
. Pada contoh di atas, hal ini terjadi: metode tersebut memutuskan koneksi yang dibuat oleh componentDidMount
. Jika logika semacam itu tidak ada, tambahkan terlebih dahulu.
Selanjutnya, pastikan metode componentDidUpdate
Anda menangani perubahan pada semua prop dan state yang Anda gunakan di componentDidMount
. Pada contoh di atas, componentDidMount
memanggil setupConnection
yang membaca this.state.serverUrl
dan this.props.roomId
. Oleh karena itu, componentDidUpdate
memeriksa apakah this.state.serverUrl
dan this.props.roomId
telah berubah, dan mereset koneksi jika iya. Jika logika componentDidUpdate
Anda tidak ada atau tidak menangani perubahan pada semua prop dan state yang relevan, perbaiki terlebih dahulu.
Pada contoh di atas, logika di dalam metode siklus hidup menghubungkan komponen ke sistem di luar React (sebuah server obrolan). Untuk menghubungkan sebuah komponen ke sistem eksternal, jelaskan logika ini sebagai sebuah Efek tunggal:
import { useState, useEffect } from 'react';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}
Panggilan useEffect
ini setara dengan logika dalam lifecycle methods di atas. Jika lifecycle methods Anda melakukan beberapa hal yang tidak terkait, pisahkan mereka menjadi beberapa Efek independen. Berikut adalah contoh lengkap yang dapat Anda coba:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [roomId, serverUrl]); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> </> ); }
Migrasi komponen dengan context
dari kelas ke fungsi
Pada contoh ini, kelas komponen Panel
dan Button
membaca context dari this.context
:
import { createContext, Component } from 'react'; const ThemeContext = createContext(null); class Panel extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'panel-' + theme; return ( <section className={className}> <h1>{this.props.title}</h1> {this.props.children} </section> ); } } class Button extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'button-' + theme; return ( <button className={className}> {this.props.children} </button> ); } } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }
Ketika Anda mengonversi ke komponen fungsi, ubah this.context
dengan memanggil useContext
:
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }