代码拉取完成,页面将自动刷新
import * as React from "react"
import { use, useState, startTransition } from "react"
import { createFromFetch } from "react-server-dom-webpack"
import { hydrateRoot } from 'react-dom/client';
// 客户端路由缓存
let clientJSXCache = {}
let currentPathname = window.location.pathname
let updateRoot
function Shell({ data }) {
const [root, setRoot] = useState(use(data))
clientJSXCache[currentPathname] = root
updateRoot = setRoot
return root
}
let data = createFromFetch(
fetch(currentPathname + '?jsx')
)
hydrateRoot(document, React.createElement(Shell, { data }))
async function navigate(pathname, revalidate) {
currentPathname = pathname;
if (!revalidate && clientJSXCache[pathname]) {
updateRoot(clientJSXCache[pathname])
return
} else {
const response = fetch(pathname + '?jsx')
const root = await createFromFetch(response)
clientJSXCache[pathname] = root
startTransition(() => {
updateRoot(root)
})
}
}
window.addEventListener("click", (e) => {
// 忽略非 <a> 标签点击事件
if (e.target.tagName !== "A") {
return;
}
// 忽略 "open in a new tab".
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
return;
}
// 忽略外部链接
const href = e.target.getAttribute("href");
if (!href.startsWith("/")) {
return;
}
// 组件浏览器重新加载页面
e.preventDefault();
// 但是 URL 还是要更新
window.history.pushState(null, null, href);
// 调用我们自己的导航逻辑
navigate(href);
}, true);
window.addEventListener("popstate", () => {
// 处理浏览器前进后退事件
navigate(window.location.pathname);
});
window.addEventListener("submit", async (e) => {
const action = e.target.action
const actionURL = new URL(action, window.location.origin)
if (!actionURL.pathname.startsWith("/actions/")) {
return
}
e.preventDefault()
if (e.target.method === "post") {
const formData = new FormData(e.target)
const body = Object.fromEntries(formData.entries())
const response = await fetch(action, {
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
},
})
if (!response.ok) return
navigate(window.location.pathname, true)
return
} else {
console.error("unknown method", e.target.method)
}
})
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。