React-with-Golang-示例

参考 blog

环境搭建

需要安装 create-react-app 以及 go, 在 Archlinux 上为:

1
2
sudo pacman -S go
sudo npm install -g create-react-app

(这里是全局安装 create-react-app)

创建项目以及启动一个 http 服务

1
2
3
npx create-react-app my-react-app
cd my-react-app
npm start

用 go 启用一个基础的 HTTP server 监听端口以及处理请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello from Golang server!"))
})

http.ListenAndServe(":8080", nil)
}

Golang 中处理 HTTP 请求的方法

利用 net/http 库, 需要定义:

  • 访问路径, 如 /api/data
  • 处理函数, 如 dataHandler
  • 监听接口, 如 :8080
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import (
"net/http"
)

func main() {
http.HandleFunc("/api/data", dataHandler)
http.ListenAndServe(":8080", nil)
}

func dataHandler(w http.ResponseWriter, r *http.Request) {
// Process the request and send back a response
}

将 Golang 数据结构以 JSON 形式返回响应

1
2
3
4
5
6
7
8
9
type ApiResponse struct {
Message string `json:"message"`
}


func dataHandler(w http.ResponseWriter, r *http.Request) {
response := ApiResponse{Message: "Hello from the Golang API!"}
json.NewEncoder(w).Encode(response)
}

React 前端向 Golang 后端发起请求

fetch API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ./fetch/test.js
import { useState, useEffect } from 'react';

export default function Test() {
const [data, setData] = useState(null);

async function fetchData() {
try {
const response = await fetch('http://localhost:8080/');
const data = await response.json();
setData(data)
} catch (error) {
console.error('Error: ', error);
}
}

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

if (!data) {
return <div>Loading...</div>
}

return (
<h1>{data.message}</h1>
);
}

React 前端创建来自用户的请求

1
2
3
4
5
6
7
8
9
10
11
import Test from "./fetch/test"

function App() {
return (
<div>
<Test />
</div>
);
}

export default App;

Go Server 处理静态文件

1
2
3
4
5
6
7
8
9
func main() {
fs := http.FileServer(http.Dir("build"))
http.Handle("/", fs)

// API routes
http.HandleFunc("/api/data", dataHandler)

http.ListenAndServe(":8080", nil)
}
  • http.FileServer(http.Dir("build")) 创建了一个 HTTP 文件服务器, 它将服务于 build 目录中的静态文件
  • http.Handle("/", fs) 将这个文件服务器注册为根路径 / 的处理器
  • 当客户端访问根路径 (例如 http://localhost:8080/) 时, Go 服务器将自动从 build 目录中提供相应的静态文件
  • http.HandleFunc("/api/data", dataHandler) 注册了一个名为 dataHandler 的函数, 用于处理 /api/data 路径的请求
  • 当客户端访问 /api/data 路径时, Go 服务器将调用 dataHandler 函数来处理该请求

另一种更好的组织方法:

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
// Static files
fs := http.FileServer(http.Dir("build"))
http.Handle("/", fs)

// API routes
api := http.NewServeMux()
api.HandleFunc("/api/data", dataHandler)
http.Handle("/api/", api)

http.ListenAndServe(":8080", nil)
}
  • http.ServeMux 是 Go 标准库中的一个 HTTP 请求多路复用器 (路由器), 可以处理 HTTP 请求的路由和分发

原本的对 /api/data 请求是注册到 / 路径下的, 在与 / 绑定的文件服务器 fs 下找静态资源, 而这样写后就将 /api/data 相关的请求都注册到 /api/ 路径下, 在 api 这一 http.ServeMux 下找资源.

热加载开发环境

React 自然支持, 对于 Golang 可以使用类似 fresh 的工具:

1
2
go install github.com/pilu/fresh@latest
fresh

Debug 技巧

对于 React 使用 console.log.

对于 Golang 用 error 类型:

1
2
3
4
5
6
7
8
9
func dataHandler(w http.ResponseWriter, r *http.Request) {
// Simulate an error
err := errors.New("an error occurred")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Normal processing
}

React 部分的测试

也可以考虑 Jest 或 React Testing 库:

1
2
3
4
5
6
7
8
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

Golang 部分的测试

测试 API Endpoints, 用 net/http/httptest 库:

1
2
3
4
5
6
7
8
9
10
11
12
13
func TestApiHandler(t *testing.T) {
req, err := http.NewRequest("GET", "/api/data", nil)
if err != nil {
t.Fatal(err)
}

rr := httptest.NewRecorder()
handler := http.HandlerFunc(dataHandler)

handler.ServeHTTP(rr, req)

// Check the status code and response body
}

构建二进制

对于 React:

1
npm run build

对于 Golang:

1
go build -o myapp

React-with-Golang-示例
http://example.com/2024/07/27/React-with-Golang-示例/
作者
Jie
发布于
2024年7月27日
许可协议