設定

那我們怎麼在Next.js裡取得資料??

首先,我們先拿前面的範例,再從範例裡修改

import { Box, Container, List, ListItem, ListItemText } from "@mui/material";
//import { lightBlue } from "@mui/material/colors";

export default function ProductList() {
  const [products, setProducts] = useState([
    { desc: "iPad", price: 20000 },
    { desc: "iPhone 8", price: 20000 },
    { desc: "iPhone X", price: 30000 }
  ]);  return (
    <Container maxWidth="sm">
    <Box >
      <List subheader="Product list" aria-label="product list">
        {products.map((product) =>
          <ListItem divider key={product.desc}>
            <ListItemText primary={product.desc} secondary={product.price}>
            </ListItemText>
          </ListItem>)}
      </List>
    </Box>
    </Container>
  );
}

Axios

可以使用javascript內建的fetch()來呼叫API,不過,通常會使用axios來呼叫API。

首先,安裝axios套件:

npm i axios

image.png

讀取資料

我們利用axios裡的get(),呼叫api。

首先import套件:

import axios from "axios";
const response = await axios.get('<http://localhost:8000/product>'); 

因為這是個非同步的呼叫,所以,要利用await去等待結果。respone會得到很多內容,其中,我們所需要的資料是在data裡,所以,利用setProduct()去更新products的內容。由於我們使用了await,這個function就要加上async。

  **async** function getProducts() {
    try {
      const response = await axios.get('<http://localhost:8000/product>');      
      **setProducts(()=>[...response.data])**
    } catch (error) {
      console.error(error);
    }
  }

useEffect()

如果直接在程式裡呼叫getProducts(),因為當我們setProducts()時,會重新reder畫面,那又會再執行一次getProducts(),就會產生無窮迴圈。所以,我們必須利用useEffect()。useEffect()有兩個參數,第一個參數是要呼叫的函數,第二個參數是要監控的變數,當這些變數被異動時,函數就會被呼叫,所以,前面這個函數就是個call back function。當第二個參數是個空陣列,這函數只會被呼叫一次。

記得要import: