所以基本上我在应用程序目录中有一个服务器组件,我想获取路径名。我尝试使用 window.location 来做到这一点,但它不起作用。我有什么办法可以做到这一点吗?
在 NextJs 13+ 中,使用实验性 App 文件夹,可以编写异步服务器组件,如文档所述:
export default async function Page({ params: { username } }) {
// Initiate both requests in parallel
const artistData = getArtist(username);
const albumsData = getArtistAlbums(username);
// Wait for the promises to resolve
const [artist, albums] = await Promise.all([artistData, albumsData]);
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
这是一项非常有用的技术,我已经在应用程序的许多页面中实现了。但是,当使用 jest 进行测试时,我发现我无法编写任何能够呈现此默认导出的测试:
it('should render without crashing', async () => {
...(setup mocks)
const { container } = await waitFor(() => render(<Page …Run Code Online (Sandbox Code Playgroud) typescript jestjs next.js react-testing-library react-server-components
我\xe2\x80\x99已经使用React服务器组件近两周了,这个问题一直让我伤脑筋:如何为服务器组件提供上下文?例如,提供一个主题(例如深色|浅色模式)?我已经检查了 Nextjs 文档很多次,并且读到了同样的内容,就好像它会改变一样。它声明只有客户端组件可以使用Context。那么,如果服务器组件需要不基于服务器的数据,它将如何使用Context?我可以\xe2\x80\x99t 获取基于状态的数据。有没有人想办法解决这个问题?
\n <html>\n <body className="page-container">\n <ThemeProvider>\n {children} // Combination of Server and Client components\n </ThemeProvider>\n </body>\n </html>\nRun Code Online (Sandbox Code Playgroud)\nexport default async function ServerComponent(){\n ...\n const theme = useContext(ThemeContext) // Would give an error; not a client component\n ...\n return (\n <div className={theme}>\n ...\n </div>\n)\n}\nRun Code Online (Sandbox Code Playgroud)\n我已经完成了 Next.js beta 文档中所说的所有内容:将提供程序放在客户端组件中,并让服务器组件成为所述客户端组件的子组件。现在,我只是想知道如何使用服务器组件中的上下文;它适用于客户端组件,因为它们允许使用钩子,但不适用于服务器组件。
\njavascript reactjs react-context react-server-components next.js13
我很好奇我们如何能够访问 Next.js 13 的 alpha 版本服务器操作的返回值。这是Next 团队的文档供参考。
假设我有以下示例服务器操作来执行输入验证:
async function validation(formData: FormData) { // needs "formData" or else errors
'use server';
// Get the data from the submitted form
const data = formData?.get("str");
// Sanitize the data and put it into a "str" const
const str = JSON.stringify(data)
.replace(/['"]+/g, '')
// Self explanatory
if (!str) {
return { error: "String is Required" }
}
else if (!(/^[a-zA-Z0-9]{8}$/).test(str)) {
return { error : "Invalid String Format" }
}
// Using …Run Code Online (Sandbox Code Playgroud) validation reactjs next.js react-server-components next.js13
我试图了解 React 服务器组件以及如何在不使用 useState 和 useEffect 的情况下渲染组件状态。我创建了一个带有嵌入式客户端组件的服务器组件,两者都获取少量数据并显示为 JSON。
客户端组件按预期工作并呈现从 API 获取的 json 数据。
主客户端.tsx
import { useEffect, useState } from "react"
export default function Main() {
let [data, setData] = useState(undefined);
async function fetchData() {
let value = await fetch("https://jsonplaceholder.typicode.com/posts");
let result = await value.json();
let slice = result.slice(0,2);
return slice;
}
useEffect(()=>{
fetchData().then(value => {
setData(value);
console.log("data", data)
});
}, [])
return (<div className="component">
<h1>Client Main</h1>
{data &&
<div>
<pre>
{JSON.stringify(data, null, 2)}
</pre>
</div>
}
</div>)
}
Run Code Online (Sandbox Code Playgroud)
服务器组件不会重新渲染 …
我正在从返回随机笑话的 api 中获取(使用 Nextjs 13 的fetchwith )。{cache:'force-cache'}我注意到fetch在构建过程中被调用了两次。
这是我的代码:
// page.js
import {RefreshButton} from './RefreshButton'
async function getRandomJoke(){
const res = await fetch("https://v2.jokeapi.dev/joke/Programming?type=single", {cache:'force-cache'})
const data = await res.json()
console.log("fetch called. Joke is: ", data['joke'])
return data['joke']
}
export default async function Home() {
const joke = await getRandomJoke()
return (
<div>
{joke}
<RefreshButton/>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
这是构建日志:
[= ] info - Generating static pages (2/3)fetch called. Joke is: A programmer puts two glasses on …Run Code Online (Sandbox Code Playgroud) 我有一个服务器组件InitView;
const InitView = () => {
useEffect(() => { });
return (
<>
<Hero/>
<span className="text-xl font-normal text-gray-100">Now, how do you want to play?</span>
<GameModeMenu/>
</>
);
}
export default InitView;
Run Code Online (Sandbox Code Playgroud)
我还有一个服务器组件View;
interface ViewProps {
children?: React.ReactNode;
}
const View = ({children}:ViewProps) => {
return (
<main className="home w-screen h-screen flex flex-col gap-10 justify-start items-center bg-neutral-900 px-8 py-10">
{children}
</main>
);
}
export default View;
Run Code Online (Sandbox Code Playgroud)
这是我的page.tsx
export default function Page() {
return (
<View> …Run Code Online (Sandbox Code Playgroud) 目前正在尝试重构我们的项目以使用服务器组件(app 目录),第一个挑战是如何使用新的“app”目录实现无限滚动分页。
这是一个过于简化的页面示例:
import OrganisationInterface from "@/interfaces/OrganisationInterface";
async function getData() {
const res = await fetch('http://api.test/v1/organisations?page=1');
if (!res.ok) {
throw new Error('Failed to fetch data');
}
return res.json();
}
export default async function Page() {
const { data } = await getData();
return (
<>
<div className="mx-auto in-h-screen ">
{data && data.map((organisation: OrganisationInterface) => (
<div key={organisation.id}>
{organisation.attributes.title.lt}
</div>
))}
</div>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
我在服务器上预取了 10 个初始结果,现在我需要发出客户端请求以添加另外 10,20,30...
或者我应该以某种方式在服务器端执行此操作?我需要一些如何正确实现这一点的想法或示例,之前的解决方案完全基于客户端,使用 SWR 或 ReactQuery。
让我们考虑一下在构建期间获取分页的前 3 页的示例:
\napp/listing-params/[page]/page.jsx
const getData = async (page) =>\n new Promise((resolve) => {\n setTimeout(() => {\n resolve(`You are on page ${page}`);\n }, 1000);\n });\n\nexport async function generateStaticParams() {\n return [{ page: \'1\' }, { page: \'2\' }, { page: \'3\' }];\n}\n\nexport default async function Page({ params }) {\n const data = await getData(params.page);\n\n return <div>{data}</div>;\n}\nRun Code Online (Sandbox Code Playgroud)\n这将生成路线:
\nRoute (app) Size First Load JS\n\xe2\x94\x9c \xe2\x97\x8f /listing-params/[page] 145 B 79.5 kB\n\xe2\x94\x9c \xe2\x94\x9c /listing-params/1\n\xe2\x94\x9c \xe2\x94\x9c /listing-params/2\n\xe2\x94\x94 \xe2\x94\x94 /listing-params/3\n\n+ First …Run Code Online (Sandbox Code Playgroud) 我正在使用 Next.js 并测试他们的新数据获取方式,但这也可能是一个常见的 React 18+ 问题,因为库本身正在转向客户端和服务器组件之间的区别。
假设我有这样的设置:
// page.tsx (server component)
export default function Home() {
return (
<>
<Search /> {/* Search is a client component that tracks state for an input */}
<ServerData /> {/* ServerData is a server component that gets the initial data */}
</>
)
}
Run Code Online (Sandbox Code Playgroud)
由于Search跟踪input状态,我如何使用该值并对 进行客户端过滤器ServerData?
我尝试过的:
Search可以是接受孩子道具的客户端组件。page.tsx可以重构,以便SearchData作为子项传递给 Search 并ServerData可以接受输入 prop。这可能行不通,因为我无法传递input到ServerDataasSearch只能将其理解为children …
next.js ×8
reactjs ×8
next.js13 ×6
javascript ×2
jestjs ×1
path ×1
react-18 ×1
router ×1
server ×1
typescript ×1
validation ×1