componentDidMount setara pada fungsi React / komponen Hooks?

99

Adakah cara untuk mensimulasikan componentDidMountdalam komponen fungsional React melalui hook?

jeyko
sumber

Jawaban:

199

Untuk versi hook yang stabil (Versi React 16.8.0+)

Untuk componentDidMount

useEffect(() => {
  // Your code here
}, []);

Untuk componentDidUpdate

useEffect(() => {
  // Your code here
}, [yourDependency]);

Untuk componentWillUnmount

useEffect(() => {
  // componentWillUnmount
  return () => {
     // Your code here
  }
}, [yourDependency]);

Jadi dalam situasi ini, Anda perlu meneruskan ketergantungan Anda ke dalam array ini. Anggap saja Anda memiliki keadaan seperti ini

const [count, setCount] = useState(0);

Dan setiap kali jumlah bertambah, Anda ingin merender ulang komponen fungsi Anda. Maka Anda useEffectakan terlihat seperti ini

useEffect(() => {
  // <div>{count}</div>
}, [count]);

Dengan cara ini setiap kali hitungan Anda diperbarui, komponen Anda akan dirender ulang. Semoga ini bisa sedikit membantu.

Mertcan Diken
sumber
Penjelasan menyeluruh! Apakah ada cara untuk mensimulasikan componentDidReceiveProps?
jeyko
1
Saya tidak menyadarinya bahkan jika itu ada. Anda dapat memeriksa utas ini untuk itu melalui github.com/facebook/react/issues/3279
Mertcan Diken
1
Terima kasih untuk ini karena saya tidak mengetahui argumen kedua dalam useState. Kepada siapa pun yang membaca ini, harap diingat bahwa meninggalkan argumen kedua undefinedakan menyebabkan efek Anda terpicu pada setiap render (jika saya tidak salah).
dimiguel
Apakah yang Anda maksud adalah dependensi useEffect (meneruskan array dependensi)? Jika demikian ya jika Anda membiarkannya kosong, itu adalah bug dalam kode. Untuk dekonstruksi array, Anda memerlukan [count, setCount] karena count adalah variabel status Anda dalam contoh ini dan setCount adalah fungsi Anda untuk memperbarui status tersebut.
Mertcan Diken
Terima kasih atas jawabannya. Dokumentasi tentang ini ada di sini reactjs.org/docs/hooks-effect.html
Josh
3

Meskipun jawaban yang diterima berfungsi, itu tidak disarankan. Ketika Anda memiliki lebih dari satu status dan Anda menggunakannya dengan useEffect, itu akan memberi Anda peringatan tentang menambahkannya ke larik ketergantungan atau tidak menggunakannya sama sekali.

Terkadang menyebabkan masalah yang mungkin memberi Anda keluaran yang tidak dapat diprediksi. Jadi saya menyarankan agar Anda mengambil sedikit usaha untuk menulis ulang fungsi Anda sebagai kelas. Ada sedikit perubahan, dan Anda dapat memiliki beberapa komponen sebagai kelas dan beberapa sebagai fungsi. Anda tidak diwajibkan untuk menggunakan hanya satu konvensi.

Ambil ini sebagai contoh

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

dan

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

Ini hanya sebagai contoh . jadi jangan bicarakan tentang praktik terbaik atau potensi masalah dengan kode. Keduanya memiliki logika yang sama tetapi yang terakhir hanya berfungsi seperti yang diharapkan. Anda mungkin mendapatkan fungsionalitas componentDidMount dengan useEffect yang berjalan untuk saat ini, tetapi seiring pertumbuhan aplikasi Anda, ada kemungkinan Anda MUNGKIN menghadapi beberapa masalah. Jadi, daripada menulis ulang pada fase itu, lebih baik lakukan ini pada tahap awal.

Selain itu, OOP tidak seburuk itu, jika Pemrograman Berorientasi Prosedur sudah cukup, kita tidak akan pernah memiliki Pemrograman Berorientasi Objek. Kadang-kadang menyakitkan, tetapi lebih baik (secara teknis, selain masalah pribadi).

Aniket Kariya
sumber
1
Saya melakukan ini. Saya menghadapi masalah saat menggunakan pengait. Masalahnya hilang setelah mengubahnya menjadi kelas.
Julez
2

Tidak ada componentDidMountkomponen fungsional, tetapi React Hooks menyediakan cara Anda dapat meniru perilaku dengan menggunakan useEffecthook.

Teruskan array kosong sebagai argumen kedua useEffect()untuk menjalankan hanya callback pada pemasangan saja.

Silakan baca dokumentasi diuseEffect .

function ComponentDidMount() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log('componentDidMount');
  }, []);

  return (
    <div>
      <p>componentDidMount: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentDidMount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

Yangshun Tay
sumber
0

Anda ingin menggunakan useEffect(), yang, bergantung pada bagaimana Anda menggunakan fungsi, bisa bertindak seperti componentDidMount ().

Misalnya. Anda bisa menggunakan loadedproperti status khusus yang awalnya disetel ke false, dan mengalihkannya ke true saat render, dan hanya mengaktifkan efek saat nilai ini berubah.

Dokumentasi

markmoxx
sumber
1
Solusi ini tidak ideal. Sebaiknya gunakan nilai status hanya untuk menentukan apakah komponen telah dipasang. Selain itu, jika Anda menggunakan properti, referensi akan lebih baik karena tidak akan memicu render ulang lainnya.
Yangshun Tay
0

hook ekuivalen yang tepat untuk componentDidMount () adalah

useEffect(()=>{},[]);

semoga bermanfaat :)

Aravinth
sumber