Skip to content
This repository was archived by the owner on Mar 1, 2025. It is now read-only.

Commit 021a47b

Browse files
Merge pull request #15 from xszhangxiaocuo/main
day5:启动一个Next.js项目
2 parents 3b8e79f + 72faa1c commit 021a47b

File tree

1 file changed

+150
-2
lines changed

1 file changed

+150
-2
lines changed

Hoshino_FullStack_Compass.md

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ const element = React.createElement(
5151
);
5252
```
5353

54-
要从组件返回多个元素,必须用一个`parent tag`包裹它们,可以使用`<div></div>`或者一个空标签`<></>`
54+
- 要从组件返回多个元素,必须用一个`parent tag`包裹它们,可以使用`<div></div>`或者一个空标签`<></>`
5555

56-
JSX 要求标签明确关闭:像 `<img>` 这样的自闭合标签必须写成 `<img />`,像 `<li>oranges` 这样的包装标签必须写成 `<li>oranges</li>`
56+
- JSX 要求标签明确关闭:像 `<img>` 这样的自闭合标签必须写成 `<img />`,像 `<li>oranges` 这样的包装标签必须写成 `<li>oranges</li>`
57+
- 使用驼峰式命名
5758

5859
可以使用[转换器](https://transform.tools/html-to-jsx),将现有的`html`代码转换为`JSX`代码。
5960

@@ -118,4 +119,151 @@ function MyButton({ count, onClick }) {
118119
}
119120
```
120121

122+
### 02.22
123+
124+
React使用声明式编程,只需要声明页面需要展示的内容,React会负责操作DOM来完成页面的渲染。
125+
126+
在React中,组件就是函数,要使React正常运行,需要注意以下几点:
127+
128+
- React 组件应该大写,以区别于纯 HTML 和 JavaScript
129+
- 使用 React 组件的方式与使用常规 HTML 标签的方式相同,带有尖括号 `<>`
130+
131+
```jsx
132+
function Header() {
133+
return <h1>Develop. Preview. Ship.</h1>;
134+
}
135+
136+
const root = ReactDOM.createRoot(app);
137+
root.render(<Header />);
138+
```
139+
140+
与作为第一个函数参数传递给组件的`props`不同,`state`是初始化并存储在组件中。你可以将`state` 的信息作为`props`传递给子组件,但更新`state`的逻辑应该保留在最初创建`state`的组件中。
141+
142+
#### 如何启动一个next.js项目?
143+
144+
首先使用npm安装依赖包
145+
146+
```shell
147+
npm install react@latest react-dom@latest next@latest
148+
```
149+
150+
Next.js 使用文件系统路由。这意味着,可以使用文件夹和文件,而不是使用代码来定义应用程序的路由。
151+
152+
创建`app`文件夹,然后在该文件夹下创建`page.js`
153+
154+
```jsx
155+
import { useState } from 'react';
156+
157+
function Header({ title }) {
158+
return <h1>{title ? title : 'Default title'}</h1>;
159+
}
160+
161+
//将 export default 添加到 <HomePage> 组件,以帮助Next.js区分要呈现为页面主组件的组件。
162+
export default function HomePage() {
163+
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
164+
165+
const [likes, setLikes] = useState(0);
166+
167+
function handleClick() {
168+
setLikes(likes + 1);
169+
}
170+
171+
return (
172+
<div>
173+
<Header title="Develop. Preview. Ship." />
174+
<ul>
175+
{names.map((name) => (
176+
<li key={name}>{name}</li>
177+
))}
178+
</ul>
179+
180+
<button onClick={handleClick}>Like ({likes})</button>
181+
</div>
182+
);
183+
}
184+
```
185+
186+
在项目根目录创建`package.json`并添加以下json配置:
187+
188+
```json
189+
{
190+
"scripts": {
191+
"dev": "next dev"
192+
},
193+
"dependencies": {
194+
"next": "^14.0.3",
195+
"react": "^18.3.1",
196+
"react-dom": "^18.3.1"
197+
}
198+
}
199+
```
200+
201+
运行`npm run dev` 来启动项目,启动后页面报错:
202+
203+
![image-20250222202900283](https://minio.drivefly.cn:443/image-hoshino/blog/2025/02/22/image-20250222202900283.png)
204+
205+
这是因为 Next.js 使用了 React Server Components,这是一项允许 React 在服务器上渲染的新功能。服务器组件不支持 `useState`,因此需要改用 Client 组件。
206+
207+
项目启动后在`app`文件夹下自动创建了一个`layout.js`。这是应用程序的主要布局。可以使用它来添加在所有页面之间共享的 UI 元素(例如导航、页脚等)。
208+
209+
#### 服务端渲染与客户端渲染
210+
211+
在幕后,组件被拆分为两个模块图。**服务器模块图(或树)**包含在服务器上渲染的所有服务器组件,**客户端模块图(或树)**包含所有客户端组件。
212+
213+
服务器组件渲染后,一种称为 **React 服务器组件有效负载 (RSC)** 的特殊数据格式被发送到客户端。RSC 有效负载包含:
214+
215+
1. Server Components 的渲染结果。
216+
2. 客户端组件应呈现位置的占位符以及对其 JavaScript 文件的引用。
217+
218+
![image-20250222205729252](https://minio.drivefly.cn:443/image-hoshino/blog/2025/02/22/image-20250222205729252.png)
219+
220+
React默认在服务端进行渲染,但`useState`这样的Hook函数只能在客户端用,因此上面的写法会报错,导致页面无法渲染。
221+
222+
需要将`button`抽离为单个组件并声明在客户端进行渲染。
223+
224+
```jsx
225+
'use client'; // 在客户端渲染
226+
227+
import { useState } from 'react';
228+
229+
export default function LikeButton() {
230+
const [likes, setLikes] = useState(0);
231+
232+
function handleClick() {
233+
setLikes(likes + 1);
234+
}
235+
236+
return <button onClick={handleClick}>Like ({likes})</button>;
237+
}
238+
```
239+
240+
然后在主页面中导入这个组件即可正常渲染。
241+
242+
```jsx
243+
import LikeButton from './like-button';
244+
245+
function Header({ title }) {
246+
return <h1>{title ? title : 'Default title'}</h1>;
247+
}
248+
249+
export default function HomePage() {
250+
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
251+
252+
return (
253+
<div>
254+
<Header title="Develop. Preview. Ship." />
255+
<ul>
256+
{names.map((name) => (
257+
<li key={name}>{name}</li>
258+
))}
259+
</ul>
260+
261+
<LikeButton />
262+
</div>
263+
);
264+
}
265+
```
266+
267+
268+
121269
<!-- Content_END -->

0 commit comments

Comments
 (0)