Tự học ReactJS: Sử dụng useEffect để gọi HTTP requests

HTTP requests là một trong những side-effect thường gặp trong một website. Nó cũng tương tự các side-effect khác như tương tác với DOM hay localStorage. Các side-effect chúng ta có thể xử lý bên trong useEffect callback. Hook này đảm bảo rằng mỗi khi có sự thay đổi trong component, các side-effect được chạy lại.

Một lưu ý rằng bạn không thể return bất cứ giá trị nào trong useEffect ngoại trừ hàm để cleanup. Và một điều thú vị là:

// code này sẽ ko chạy, đừng sử dụng nó
React.useEffect(async () => {
  const result = await doSomeAsyncThing()
  // do something ...
})

Lý do code ở trên không chạy là do khi callback function trong useEffect là một async thì mặc định nó sẽ return về promise. Đây là cú pháp của async/await. Cho nên nếu bạn muốn sử dụng async/await, bạn có thể làm như sau:

React.useEffect(() => {
  async function effect() {
    const result = await doSomeAsyncThing()
    // do something with the result
  }
  effect()
})

Điều này chắc rằng bạn ko return một giá trị trong useEffect callback ngoại trừ cleanup function.

Hay bạn có thể viết như sau:

React.useEffect(() => {
  doSomeAsyncThing().then(result => {
    // do something with the result
  })
})

Tuỳ thuộc vào bạn chọn cách viết như thế nào. Ví dụ về gọi HTTP request bên trong useEffect. Mình sử dụng axios để gọi API:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ hits: [] });

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        'https://hn.algolia.com/api/v1/search?query=redux',
      );

      setData(result.data);
    };

    fetchData();
  }, []);

  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;

thaunguyen.com via Epic React by Kent C.Dodds

4 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *