我有一个计数器和一个console.log()来useEffect记录我状态中的每个变化,但是useEffect在挂载时被调用两次。我正在使用 React 18。这是我项目的CodeSandbox和以下代码:
import { useState, useEffect } from "react";
const Counter = () => {
const [count, setCount] = useState(5);
useEffect(() => {
console.log("rendered", count);
}, [count]);
return (
<div>
<h1> Counter </h1>
<div> {count} </div>
<button onClick={() => setCount(count + 1)}> click to increase </button>
</div>
);
};
export default Counter;
Run Code Online (Sandbox Code Playgroud) app当我使用以下简单组件时,它会在 Next.js 的目录中抛出以下错误useState:
您正在导入需要 useState 的组件。它仅在客户端组件中工作,但其父组件都没有标记为“使用客户端”,因此默认情况下它们是服务器组件。
import { useState } from "react";
export default function Card() {
const [state, setState] = useState("");
return <></>;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 Next.js 13 中的实验app文件夹,它们已替换next/router为next/navigation,因此我useRouter相应地导入了挂钩。pathname我在路由器中没有看到该属性,该属性确实存在于next/router的路由器中。
类型“AppRouterInstance”上不存在属性“路径名”
我的用例是突出显示用户当前所在的导航栏中的链接。这是我尝试过的:
import Link from "next/link";
import { useRouter } from 'next/navigation';
const StyledNavLink: React.FC<NavLinkProps> = ({ to, children }) => {
const router = useRouter();
...
return (
<Link href={to} className={getNavLinkClass({isActive: router.pathname === to})}>
{children}
</Link>
);
};
Run Code Online (Sandbox Code Playgroud)
我可以做些什么来获取当前路径名或其他东西来将我的类添加到活动链接中吗?
我仍在尝试理解这个场景。谁能建议在 Next.js 13 中执行此操作的正确方法是什么?
例如,我在服务器组件中显示用户列表,如下所示(使用 MongoDB):
// UsersList.jsx
const UsersList = () => {
const users = await usersCollection.getUsers()
return (
<div>
{users.map(user) => <div>{user}</div>}
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
在同一页面上,我还定义了用于添加用户的客户端组件:
// UsersEdit.jsx
'use client'
const UsersEdit = () => {
const handleAdd() => // calls POST to /api/users
return // render input + button
}
Run Code Online (Sandbox Code Playgroud)
两者在服务器组件页面中一起显示,如下所示:
// page.jsx
const Users = () => {
return (
<div>
<UsersList />
<UsersEdit />
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
我应该如何“重新加载”或“通知”UsersList新用户已添加到集合中以强制它显示新用户/更新的用户?
我的app/page(服务器组件)中有此代码:
const getUsers = async () => {
const result = await fetch('/api/users', {method: 'GET'});
if (result.ok) {
return result.json();
}
return [];
}
export default async function IndexPage() {
const users = await getUsers();
return (<h1>Users: {users.length}</h1>);
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
TypeError: Failed to parse URL from api/users
Run Code Online (Sandbox Code Playgroud)
如何从服务器端组件中引用 URL 的“左侧”?我能找到的所有 Next.js13示例都显示指向某个第三方服务器。Postgres 示例项目使用旧的路由器和客户端获取,使用与我使用的相同的语法。
在 Next.js 中,我都知道next/router并且next/navigation有一个useRouter()钩子,但是返回的对象不同。为什么 Next.js 在两个路由包上有相同的钩子?
导入模块时,我注意到有时导入的文件有扩展名,例如:
import { myFunc } from './foo.js';
Run Code Online (Sandbox Code Playgroud)
而其他库,导入不会:
import { myFunc } from './foo';
Run Code Online (Sandbox Code Playgroud)
这与 ES 模块与 CommonJS 模块有关吗?
我有一个根布局/app/layout.tsx和身份验证页面。我希望身份验证页面不要获取根布局,并且我在文件中为它们定义了自定义布局/app/auth/layout.tsx。
但根布局(/app/layout.tsx)包装了自定义布局(/app/auth/layout.tsx)。如何排除身份验证页面和子页面获取根布局?
我尝试将 auth 目录名称放入()as(auth)但不起作用。大多数解决方案适用于Pages Router,不适用于App Router。
我正在使用 Next.js 13.4。
我在以下位置有一个测试 API:pages\api\accounts\login.js。我正在学习新app文件夹,这仍然是 Next.js 中的一个实验性功能(截至今天)。
是否可以将我的登录脚本移至该app文件夹中?我尝试移动/重命名为app\api\accounts\login\pages.js,但是当我这样做时:
async function handler(req, res) {
console.log(res);
}
export default handler;
Run Code Online (Sandbox Code Playgroud)
我使用的网址是:http://localhost:3000/api/accounts/login。我得到:
服务器错误
错误:找不到页面的模块:/api/accounts/login
我还尝试将其移动到:app/api/accounts/login/page.js。但我得到了同样的错误。
我突然收到这个错误,不知道为什么。我没有更改版本"react-router-dom": "^6.0.0-beta.4"。但是"react-dom": "^16.8.4"“已更改为"react-dom": "^16.13.1",不知道这是否与我不知道有什么关系,但它useRoutes来自哪里"react-router-dom",这就是错误的根源。
有人知道吗?
这是我使用的 App.jsx useRoutes(routes),它给了我错误:
import React, { useEffect } from 'react';
import { AnimatePresence } from 'framer-motion';
import { connect } from 'react-redux';
import { compose } from 'recompose';
import { useRoutes } from 'react-router-dom';
import { ThemeContextProvider } from './theme/ThemeProvider';
import { getAlbumData } from './redux/albumData/albumData.actions';
import { getMetaData } from './redux/albumMetaData/albumMetaData.actions';
import {
startTagsListener,
startTagsCategoryListener,
} from './redux/global/global.actions';1111
import { withAuthentication } from …Run Code Online (Sandbox Code Playgroud)