React.js轉為Next.js並加上server side rendering

理論上大部分東西都不用更動

安裝 next.js

npm install next@latest --force

修改 package.json

主要拿掉 "react-scripts": "^3.0.1",
意即,原本 reactjs 在安裝nextjs修改前的 dependancy 段落長類似這樣

//before
"dependencies": {
 "@types/react": "^18.2.63",
 "@types/react-dom": "^18.2.20",
 "@types/react-router-dom": "^5.3.3",
 "react": "^18.2.0",
 "react-dom": "^18.2.0",
 "react-router-dom": "^6.22.2",
 "react-scripts": "^5.0.1",
 "typescript": "^5.3.3"
},

之後會成為

//after
"dependencies": {
 "@types/react": "^18.2.63",
 "@types/react-dom": "^18.2.20",
 "@types/react-router-dom": "^5.3.3",
 "@typescript-eslint/typescript-estree": "^7.1.1",
 "next": "^14.1.3",
 "react": "^18.2.0",
 "react-dom": "^18.2.0",
 "react-router-dom": "^6.22.3",
 "typescript": "^5.3.3"
},

Server Side Rendering

原本 reactjs 程式碼

// Contact1.js
import React, { useState, useEffect } from 'react';

function Contact1() {
  const [items, setItems] = useState([]);

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

  const fetchItems = async () => {
    try {
      // Fetching data from a mock API
      const response = await fetch('https://jsonplaceholder.typicode.com/posts');
      const data = await response.json();
      setItems(data);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  return (
    <div>
      <div>This is the Contact page</div>
      <ul>
        {items.map(item => (
          <li key={item["id"]}>{item["title"]}</li>
        ))}
      </ul>
    </div>
  );
}

export default Contact1;

改為 server side rendering 需要使用特定的 getServerSideProps()

import React from 'react';

function Contact({ data }: { data: DataItem[] }) {
  return (
    <div>
      <div>This is the Contact pageXXX</div>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.id}. {item.title}</li>
        ))}
      </ul>
    </div>
  );
}

export async function getServerSideProps() {
  try {
    // 從外部 API 取得資料
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    const data = await response.json();
    return {
      props: {
        data,
      },
    };
  } catch (error) {
    console.error('取得資料時發生錯誤:', error);
    return {
      props: {
        data: [],
      },
    };
  }
}

interface DataItem {
  id: number;
  title: string;
 }

export default Contact;

原本可以看到去拿外部API資料
2024-03-11 14 59 27

改為 server side rendering 就沒有了
2024-03-11 14 59 57