Pitfall

Kami merekomendasikan mendefinisikan komponen sebagai fungsi dari pada kelas. Lihat bagaimana cara migrasi.

Component adalah kelas dasar untuk komponen React yang didefinisikan segabai JavaScript classes. Kelas komponen masih disuport 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

Untuk mendefinisikan sebuah komponen React sebagai sebuah kelas, extend kelas Component bawaan dan definisikan render method:

import { Component } from 'react';

class Greeting extends Component {
render() {
return <h1>Halo, {this.props.name}!</h1>;
}
}

Hanya render method yang diperlukan, methods 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>
);
}
}

Note

Membaca this.context pada class components setara dengan useContext pada function components.

Lihat bagaimana cara migrasi.


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" />

Note

Membaca this.props pada class components setara dengan mendeklarasikan props pada function components.

Lihat bagaimana cara migrasi.


refs

Deprecated

API ini akan dihapus pada versi utama React di masa depan. Gunakan createRef sebagai gantinya.

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

Note

Mendefinisikan state pada class components setara dengan useState pada function components.

Lihat bagaimana cara migrasi.


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.

Parameters

  • props: Props awal komponen.

Returns

constructor seharusnya tidak mengembalikan apapun.

Caveats

  • 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 menjadi undefined 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 menggunakan this.setState() sebagai gantinya. Jangan memanggil setState di dalam constructor.

  • Ketika Anda menggunakan pe-render-an di server, constructor juga akan dijalankan di server, diikuti oleh metode render. Namun, lifecycle methods seperti componentDidMount atau componentWillUnmount 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 dari constructor.

Note

Tidak ada yang setara dengan constructor pada function components. Untuk mendeklarasikan state pada function component, panggil useState. Untuk menghindari perhitungan ulang pada state awal, oper fungsi ke useState.


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.

Lihat contoh.

Parameters

  • error: Error yang dilempar. Pada praktiknya, biasanya akan berupa sebuah instance dari Error tetapi ini tidak dijamin karena JavaScript memungkinkan untuk throw nilai apa pun, termasuk string atau bahkan null.

  • info: Objek yang berisi informasi tambahan tentang error. Field componentStack 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.

Returns

componentDidCatch seharusnya tidak mengembalikan apapun.

Caveats

  • Di masa lalu, umumnya memanggil setState di dalam componentDidCatch untuk memperbarui antarmuka pengguna(UI) dan menampilkan pesan kesalahan pengganti. Ini sudah ditinggalkan karena mendefinisikan static getDerivedStateFromError.

  • Build produksi dan pengembangan dari React sedikit berbeda dalam cara componentDidCatch menangani kesalahan. Pada pengembangan, kesalahan akan naik ke window, yang berarti window.onerror atau window.addEventListener('error', callback) akan menangkap kesalahan yang telah ditangkap oleh componentDidCatch. Pada produksi, sebaliknya, kesalahan tidak akan naik, yang berarti penangan kesalahan induk hanya akan menerima kesalahan yang tidak ditangkap secara eksplisit oleh componentDidCatch.

Note

Belum ada yang setara dengan componentDidCatch pada function components. Jika Anda ingin menghindari membuat class components, tulis satu komponen ErrorBoundary seperti di atas dan gunakan di seluruh aplikasi Anda. Sebagai alternatif, Anda dapat menggunakan paket react-error-boundary yang akan melakukannya untuk Anda.


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

// ...
}

Lihat contoh lebih banyak.

Parameters

componentDidMount tidak mengambil parameter apa pun.

Returns

componentDidMount seharusnya tidak mengembalikan apapun.

Caveats

  • Ketika Strict Mode aktif, di pengembangan React kan memanggil componentDidMount, kemudian segera memanggil componentWillUnmount, dan kemudian memanggil componentDidMount lagi. Ini membantu Anda melihai jika Anda lupa untuk mengimplementasikan componentWillUnmount atau jika logikanya tidak sepenuhnya “mencerminkan” apa yang dilakukan oleh componentDidMount.

  • Meskipun Anda dapat langsung memanggil setState di componentDidMount, sebaiknya hindari hal itu jika bisa. Ini akan memicu render-ing ekstra, tetapi itu akan terjadi sebelum browser memperbarui layar. Ini menjamin bahwa meskipun render 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 di constructor 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.

Note

Untuk banyak kasus penggunaan, mendefinisikan componentDidMount, componentDidUpdate, dan componentWillUnmount bersama pada class components itu setara dengan memanggil useEffect pada function components. Dalam kasus yang jarang terjadi di mana penting bagi kode untuk dijalankan sebelum tampilan browser dilakukan, useLayoutEffect merupakan pilihan yang lebih tepat.

Lihat bagaimana cara migrasi.


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

// ...
}

Lihat contoh lebih banyak.

Parameters

  • prevProps: Props sebelum update. Membandingkan prevProps ke this.props untuk menentukan apa yang berubah.

  • prevState: State sebelum update. Membandingkan prevState ke this.state untuk menentukan apa yang berubah.

  • snapshot: Jika Anda mengimplementasikan getSnapshotBeforeUpdate, snapshot akan berisi nilai yang Anda kembalikan dari metode tersebut. Jika tidak, nilainya akan undefined.

Returns

componentDidUpdate seharusnya tidak mengembalikan apapun.

Caveats

  • componentDidUpdate tidak akan dipanggil jika shouldComponentUpdate didefinisikan dan mengembalikan false.

  • Logika di dalam componentDidUpdate biasanya harus dibungkus dalam kondisi yang membandingkan this.props dengan prevProps, dan this.state dengan prevState. Jika tidak, ada risiko terjadi perulangan tak terbatas.

  • Meskipun Anda dapat memanggil setState langsung di dalam componentDidUpdate, sebaiknya hindari hal itu jika memungkinkan. Ini akan memicu render tambahan, tetapi akan terjadi sebelum browser memperbarui tampilan. Ini menjamin bahwa meskipun render 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.

Note

Untuk banyak kasus penggunaan, mendefinisikan componentDidMount, componentDidUpdate, dan componentWillUnmount bersama dalam class components setara dengan menggunakan useEffect di function components. Dalam kasus yang jarang terjadi di mana penting bagi kode untuk dijalankan sebelum tampilan browser, useLayoutEffect adalah pilihan yang lebih tepat.

Lihat bagaimana cara migrasi.


componentWillMount()

Deprecated

API ini telah diganti namanya dari componentWillMount ke UNSAFE_componentWillMount. Nama lama sudah tidak digunakan lagi. Di versi utama React yang akan datang, hanya nama baru yang akan berfungsi.

Jalankan rename-unsafe-lifecycles codemod untuk memperbaruhi komponen Anda secara otomatis.


componentWillReceiveProps(nextProps)

Deprecated

API ini telah diganti namanya dari componentWillReceiveProps ke UNSAFE_componentWillReceiveProps. Nama lama sudah tidak digunakan lagi. Di versi utama React yang akan datang, hanya nama baru yang akan berfungsi.

Jalankan rename-unsafe-lifecycles codemod untuk memperbaruhi komponen Anda secara otomatis.


componentWillUpdate(nextProps, nextState)

Deprecated

API ini telah diganti namanya dari componentWillUpdate ke UNSAFE_componentWillUpdate. Nama lama sudah tidak digunakan lagi. Di versi utama React yang akan datang, hanya nama baru yang akan berfungsi.

Jalankan rename-unsafe-lifecycles codemod untuk memperbaruhi komponen Anda secara otomatis.


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

// ...
}

Lihat contoh lebih banyak.

Parameters

componentWillUnmount tidak mengambil parameter apapun.

Returns

componentWillUnmount seharusnya tidak mengembalikan apapun.

Caveats

  • Ketika Strict Mode aktif, pada development React akan memanggil componentDidMount, kemudian segera memanggil componentWillUnmount, dan kemudian memanggil componentDidMount lagi. Ini membantu Anda memperhatikan jika Anda lupa menerapkan componentWillUnmount atau jika logikanya tidak sepenuhnya “mencerminkan” apa yang componentDidMount lakukan.

Note

Untuk banyak kasus penggunaan, mendefinisikan componentDidMount, componentDidUpdate, dan componentWillUnmount bersama pada class components setara dengan memanggil useEffect pada function components. Dalam kasus yang jarang terjadi di mana penting bagi kode untuk dijalankan sebelum tampilan browser, useLayoutEffect adalah pilihan yang lebih tepat.

Lihat bagaimana cara migrasi.


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.

Parameters

  • optional callback Jika ditentukan, React akan memanggil callback yang Anda berikan setelah pembaruan dilakukan.

Returns

forceUpdate tidak mengembalikan apapun.

Caveats

Note

Membaca sumber data eksternal dan memaksa komponen kelas untuk me-render ulang sebagai respons terhadap perubahannya forceUpdate telah digantikan oleh useSyncExternalStore pada function components.


getChildContext()

Deprecated

API ini akan dihapus di versi utama React yang akan datang. Gunakan Context.Provider sebagai gantinya.

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) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}

componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from 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.

Parameters

  • prevProps: Props sebelum pembaharuan. Membandingkan prevProps ke this.props untuk menentukan apa yang berubah.

  • prevState: State sebelum pembaharuan. Membandingkan prevState ke this.state untuk menentukan apa yang berubah.

Returns

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.

Caveats

  • getSnapshotBeforeUpdate tidak akan dipanggil jika shouldComponentUpdate didefinisikan dan mengembalikan false.

Note

Saat ini, tidak ada yang setara dengan getSnapshotBeforeUpdate untuk function components. Kasus penggunaan ini sangat jarang, tetapi jika Anda membutuhkannya, untuk sekarang Anda harus menulis sebuah class component.


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.

Parameters

  • prevProps: Props sebelum pembaruan. Bandingkan prevProps ke this.props untuk menentukan apa yang berubah.

  • prevState: State sebelum pembaruan. Bandingkan prevState ke this.state untuk menentukan apa yang berubah.

Returns

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.

Caveats

  • render harus ditulis sebagai pure function dari props, state, dan context. Seharusnya tidak memiliki side effects.

  • render tidak akan dipanggil jika shouldComponentUpdate didefinisikan dan mengembalikan false.

  • 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 metode render.

  • Tidak ada korespondensi one-to-one antara panggilan render dan panggilan componentDidMount atau panggilan componentDidUpdate. Beberapa hasil panggilan render 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}.
</>
);
}
}

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.

Pitfall

Memanggil setState tidak mengubah state saat ini di kode yang sudah dieksekusi:

function handleClick() {
console.log(this.state.name); // "Taylor"
this.setState({
name: 'Robin'
});
console.log(this.state.name); // Still "Taylor"!
}

Ini hanya memengaruhi apa yang akan dikembalikan oleh this.state mulai dari render berikutnya.

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.

Parameters

  • nextState: Baik objek atau fungsi.

    • Jika Anda meneruskan objek sebagai nextState, objek tersebut akan digabungkan secara dangkal ke dalam this.state.
    • Jika Anda meneruskan fungsi sebagai nextState, fungsi tersebut akan diperlakukan sebagai updater function. Itu harus murni, harus mengambil state dan props yang tertunda sebagai argumen, dan harus mengembalikan objek untuk digabungkan secara dangkal ke dalam this.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.
  • opsional callback: Jika ditentukan, React akan memanggil callback yang Anda berikan setelah pembaruan dilakukan.

Returns

setState tidak mengembalikan apapun.

Caveats

  • 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 dalam flushSync, tetapi ini dapat mengganggu kinerja.

  • setState tidak segera memperbarui this.state. Hal ini membuat pembacaan this.state tepat setelah memanggil setState menjadi potensial jebakan. Sebagai gantinya, gunakan componentDidUpdate atau argumen setState callback, yang keduanya dijamin akan aktif setelah pembaruan diterapkan. Jika Anda perlu menyetel state berdasarkan state sebelumnya, Anda dapat meneruskan fungsi ke nextState seperti yang dijelaskan di atas.

Note

Memanggil setState pada class components mirip dengan memanggil fungsi set pada function components.

Lihat bagaimana cara migrasi.


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
) {
// Nothing has changed, so a re-render is unnecessary
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.

Parameters

  • nextProps: Props berikutnya yang akan dirender oleh komponen. Bandingkan nextProps dengan this.props untuk menentukan apa yang berubah.
  • nextState: State berikutnya yang akan di-render oleh komponen. Bandingkan nextState dengan this.state untuk menentukan apa yang berubah.
  • nextContext: Konteks berikutnya yang akan di-render oleh komponen. Bandingkan nextContext dengan this.context untuk menentukan apa yang berubah. Hanya tersedia jika Anda menetapkan static contextType (modern) atau static contextTypes (legacy).

Returns

Mengembalikan true jika Anda ingin komponen di-render ulang. Itu merupakan perilaku default.

Mengembalikan false untuk memberitahu React bahwa render ulang dapat dilewati.

Caveats

  • Metode ini hanya ada sebagai pengoptimalan kinerja. Jika komponen Anda rusak tanpanya, perbaiki terlebih dahulu.

  • Pertimbangkan untuk menggunakan PureComponent daripada menulis shouldComponentUpdate 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 di shouldComponentUpdate. 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.

Note

Mengoptimalkan class components dengan shouldComponentUpdate serupa dengan mengoptimalkan function components dengan memo. Function components juga menawarkan pengoptimalan yang lebih terperinci dengan useMemo.


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 setel this.state di dalam konstruktor.
  • Jika Anda perlu menjalankan efek samping atau menyiapkan langganan, pindahkan logika tersebut ke componentDidMount sebagai gantinya.

Lihat contoh migrasi dari unsafe lifecycles.

Parameters

UNSAFE_componentWillMount tidak menggunakan parameter apa pun.

Returns

UNSAFE_componentWillMount seharusnya tidak mengembalikan apa pun.

Caveats

  • UNSAFE_componentWillMount tidak akan dipanggil jika komponen mengimplementasikan static getDerivedStateFromProps atau getSnapshotBeforeUpdate.

  • Terlepas dari namanya, UNSAFE_componentWillMount tidak menjamin bahwa komponen akan dipasang jika aplikasi Anda menggunakan fitur React modern seperti Suspense. 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 ke componentDidMount.

  • UNSAFE_componentWillMount adalah satu-satunya metode siklus hidup yang berjalan selama server rendering. Untuk semua tujuan praktis, ini identik dengan constructor, sehingga Anda harus menggunakan konstruktor untuk jenis logika ini.

Note

Memanggil setState di dalam UNSAFE_componentWillMount dalam class component untuk menginisialisasi state sama dengan meneruskan state tersebut sebagai state awal ke useState dalam function components.


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.

Parameters

  • nextProps: Props berikutnya yang akan diterima komponen dari komponen induknya. Bandingkan nextProps dengan this.props untuk menentukan apa yang berubah.
  • nextContext: Props berikutnya yang akan diterima komponen dari penyedia terdekat. Bandingkan nextContext dengan this.context untuk menentukan apa yang berubah. Hanya tersedia jika Anda menetapkan static contextType (modern) atau static contextTypes (legacy).

Returns

UNSAFE_componentWillReceiveProps seharusnya tidak mengembalikan apa pun.

Caveats

  • UNSAFE_componentWillReceiveProps tidak akan dipanggil jika komponen mengimplementasikan static getDerivedStateFromProps atau getSnapshotBeforeUpdate.

  • Terlepas dari namanya, UNSAFE_componentWillReceiveProps tidak menjamin bahwa komponen akan menerima props tersebut jika aplikasi Anda menggunakan fitur React modern seperti Suspense. 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 ke componentDidUpdate.

  • UNSAFE_componentWillReceiveProps tidak berarti bahwa komponen telah menerima props yang berbeda dari sebelumnya. Anda perlu membandingkan nextProps dan this.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, memanggil setState biasanya tidak memicu UNSAFE_componentWillReceiveProps di dalam komponen yang sama.

Note

Memanggil setState dalam UNSAFE_componentWillReceiveProps pada class component untuk “menyesuaikan” state sama dengan memanggil fungsi set dari useState selama render-ing dalam function component.


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 dalam getSnapshotBeforeUpdate sebagai gantinya.

Lihat contoh migrasi dari unsafe lifecycles.

Parameters

  • nextProps: Props berikutnya yang akan di-render oleh komponen. Bandingkan nextProps dengan this.props untuk menentukan apa yang berubah.
  • nextState: State selanjutnya yang akan di-render oleh komponen. Bandingkan nextState dengan this.state untuk menentukan apa yang berubah.

Returns

UNSAFE_componentWillUpdate seharusnya tidak mengembalikan apa pun.

Caveats

  • UNSAFE_componentWillUpdate tidak akan dipanggil jika shouldComponentUpdate ditentukan dan mengembalikan false.

  • UNSAFE_componentWillUpdate tidak akan dipanggil jika komponen mengimplementasikan static getDerivedStateFromProps atau getSnapshotBeforeUpdate.

  • Tidak didukung untuk memanggil setState (atau metode apa pun yang menyebabkan setState dipanggil, seperti dispatching Redux action) selama componentWillUpdate.

  • Terlepas dari namanya, UNSAFE_componentWillUpdate tidak menjamin bahwa komponen akan diupdate jika aplikasi Anda menggunakan fitur React modern seperti Suspense. 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 ke componentDidUpdate.

  • UNSAFE_componentWillUpdate tidak berarti bahwa komponen telah menerima props atau state yang berbeda dari sebelumnya. Anda perlu membandingkan nextProps dengan this.props dan nextState dengan this.state sendiri untuk memeriksa apakah ada yang berubah.

  • React tidak memanggil UNSAFE_componentWillUpdate dengan props awal dan state selama pemasangan.

Note

Tidak ada persamaan langsung dengan UNSAFE_componentWillUpdate dalam function components.


static childContextTypes

Deprecated

API ini akan dihapus di versi utama React yang akan datang. Gunakan static contextType sebagai gantinya.

Memungkinkan Anda menentukan legacy context mana yang disediakan oleh komponen ini.


static contextTypes

Deprecated

API ini akan dihapus di versi utama React yang akan datang. Gunakan static contextType sebagai gantinya.

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

Note

Membaca this.context pada class components setara dengan useContext pada function components.

Lihat bagaimana cara migrasi.


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" />
</>

Note

Mendefinisikan defaultProps pada class components serupa dengan menggunakan default values pada function components.


static propTypes

Anda dapat mendefinisikan static propTypes bersama dengan prop-types library 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>
);
}
}

Note

Kami merekomendasikan menggunakan TypeScript daripada memeriksa prop types pada runtime.


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.

Lihat contoh.

Parameters

  • error: Kesalahan yang dilemparkan. Dalam prakteknya, biasanya akan menjadi instance dari Error tetapi ini tidak dijamin karena JavaScript memungkinkan untuk throw nilai apa saja, termasuk strings atau bahkan null.

Returns

static getDerivedStateFromError harus mengembalikan state yang memberi tahu komponen untuk menampilkan pesan kesalahan.

Caveats

  • static getDerivedStateFromError harus berupa pure function. Jika Anda ingin melakukan efek samping (misalnya, untuk memanggil layanan analitik), Anda juga perlu mengimplementasikan componentDidCatch.

Note

Belum ada padanan langsung untuk static getDerivedStateFromError dalam function components. Jika Anda ingin menghindari pembuatan class components, tulis satu komponen ErrorBoundary seperti di atas dan gunakan di seluruh aplikasi Anda. Sebagai alternatif, gunakan packagereact-error-boundary yang melakukan itu.


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) {
// Any time the current user changes,
// Reset any parts of state that are tied to that user.
// In this simple example, that's just the 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).

Pitfall

Deriving state mengarah ke kode verbose dan membuat komponen Anda sulit untuk dipikirkan. Pastikan Anda terbiasa dengan alternatif yang lebih sederhana:

Parameters

  • props: Props berikutnya yang akan di-render oleh komponen.
  • state: State berikutnya yang akan di-render oleh komponen.

Returns

static getDerivedStateFromProps mengembalikan objek untuk memperbarui state, atau null untuk tidak memperbarui apa pun.

Caveats

  • 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 dari setState 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.

Note

Menerapkan static getDerivedStateFromProps pada class component setara dengan memanggil fungsi set dari useState selama rendering pada function component.


Usage

Mendefinisikan class component

Untuk mendefinisikan komponen React sebagai sebuah class, extend Component class bawaan dan definisikan render method:

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

Note that Hooks (functions starting with use, like useState) are not supported inside class components.

Pitfall

We recommend defining components as functions instead of classes. See how to migrate.


Adding state to a class component

To add state to a class, assign an object to a property called state. To update state, call 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>
      </>
    );
  }
}

Pitfall

We recommend defining components as functions instead of classes. See how to migrate.


Adding lifecycle methods to a class component

There are a few special methods you can define on your class.

If you define the componentDidMount method, React will call it when your component is added (mounted) to the screen. React will call componentDidUpdate after your component re-renders due to changed props or state. React will call componentWillUnmount after your component has been removed (unmounted) from the screen.

If you implement componentDidMount, you usually need to implement all three lifecycles to avoid bugs. For example, if componentDidMount reads some state or props, you also have to implement componentDidUpdate to handle their changes, and componentWillUnmount to clean up whatever componentDidMount was doing.

For example, this ChatRoom component keeps a chat connection synchronized with props and 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>
      </>
    );
  }
}

Note that in development when Strict Mode is on, React will call componentDidMount, immediately call componentWillUnmount, and then call componentDidMount again. This helps you notice if you forgot to implement componentWillUnmount or if its logic doesn’t fully “mirror” what componentDidMount does.

Pitfall

We recommend defining components as functions instead of classes. See how to migrate.


Catching rendering errors with an error boundary

By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an error boundary. An error boundary is a special component that lets you display some fallback UI instead of the part that crashed—for example, an error message.

To implement an error boundary component, you need to provide static getDerivedStateFromError which lets you update state in response to an error and display an error message to the user. You can also optionally implement componentDidCatch to add some extra logic, for example, to log the error to an analytics service.

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}

componentDidCatch(error, info) {
// Example "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) {
// You can render any custom fallback UI
return this.props.fallback;
}

return this.props.children;
}
}

Then you can wrap a part of your component tree with it:

<ErrorBoundary fallback={<p>Something went wrong</p>}>
<Profile />
</ErrorBoundary>

If Profile or its child component throws an error, ErrorBoundary will “catch” that error, display a fallback UI with the error message you’ve provided, and send a production error report to your error reporting service.

You don’t need to wrap every component into a separate error boundary. When you think about the granularity of error boundaries, consider where it makes sense to display an error message. For example, in a messaging app, it makes sense to place an error boundary around the list of conversations. It also makes sense to place one around every individual message. However, it wouldn’t make sense to place a boundary around every avatar.

Note

There is currently no way to write an error boundary as a function component. However, you don’t have to write the error boundary class yourself. For example, you can use react-error-boundary instead.


Alternatives

Migrating a simple component from a class to a function

Typically, you will define components as functions instead.

For example, suppose you’re converting this Greeting class component to a function:

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

Define a function called Greeting. This is where you will move the body of your render function.

function Greeting() {
// ... move the code from the render method here ...
}

Instead of this.props.name, define the name prop using the destructuring syntax and read it directly:

function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}

Here is a complete example:

function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

export default function App() {
  return (
    <>
      <Greeting name="Sara" />
      <Greeting name="Cahal" />
      <Greeting name="Edite" />
    </>
  );
}


Migrating a component with state from a class to a function

Suppose you’re converting this Counter class component to a function:

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

Start by declaring a function with the necessary state variables:

import { useState } from 'react';

function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
// ...

Next, convert the 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);
}
// ...

Finally, replace all references starting with this with the variables and functions you defined in your component. For example, replace this.state.age with age, and replace this.handleNameChange with handleNameChange.

Here is a fully converted component:

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


Migrating a component with lifecycle methods from a class to a function

Suppose you’re converting this ChatRoom class component with lifecycle methods to a function:

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

First, verify that your componentWillUnmount does the opposite of componentDidMount. In the above example, that’s true: it disconnects the connection that componentDidMount sets up. If such logic is missing, add it first.

Next, verify that your componentDidUpdate method handles changes to any props and state you’re using in componentDidMount. In the above example, componentDidMount calls setupConnection which reads this.state.serverUrl and this.props.roomId. This is why componentDidUpdate checks whether this.state.serverUrl and this.props.roomId have changed, and resets the connection if they did. If your componentDidUpdate logic is missing or doesn’t handle changes to all relevant props and state, fix that first.

In the above example, the logic inside the lifecycle methods connects the component to a system outside of React (a chat server). To connect a component to an external system, describe this logic as a single Effect:

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

// ...
}

This useEffect call is equivalent to the logic in the lifecycle methods above. If your lifecycle methods do multiple unrelated things, split them into multiple independent Effects. Here is a complete example you can play with:

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

Note

If your component does not synchronize with any external systems, you might not need an Effect.


Migrating a component with context from a class to a function

In this example, the Panel and Button class components read context from 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>
  )
}

When you convert them to function components, replace this.context with useContext calls:

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