Web 开发 10
其实我很喜欢跟练workshop,这种虽然是没有掌握太多知识,也能看到自己一步一步在完善一个小项目的感觉特别好!特别是能跑通了以后(跑不通就是红温了报错了哈哈...痛并快乐着。
1 navBar导航栏
takes no props
Remember "class" attributes in HTML are renamed to "className" in ReactJS.
注意区分class和className,还有注意classname命名要用组件名开头,好像是因为react库就是这样识别的吗?
=================以上是乱记的,现在完善一下===================
一、React 中的 NavBar 导航栏组件(无 props 传递)
导航栏(NavBar)是前端常见组件,用于页面导航。在 React 中,它通常是一个无状态或有内部状态的函数组件,当不需要接收外部参数时,即为 “takes no props”。
基本示例(无 props 的 NavBar):
jsx
// NavBar.jsx
import { useState } from 'react';// 无 props 传递的导航栏组件
function NavBar() {// 可添加内部状态(如控制下拉菜单显示/隐藏)const [isMenuOpen, setIsMenuOpen] = useState(false);return (<nav className="navbar"><div className="navbar-logo">MyApp</div>{/* 桌面端导航链接 */}<div className="navbar-links"><a href="/home" className="navbar-link">首页</a><a href="/about" className="navbar-link">关于</a><a href="/contact" className="navbar-link">联系</a></div>{/* 移动端菜单按钮 */}<button className="navbar-toggle"onClick={() => setIsMenuOpen(!isMenuOpen)}>菜单</button>{/* 移动端下拉菜单(根据状态显示) */}{isMenuOpen && (<div className="navbar-mobile-links"><a href="/home" className="navbar-mobile-link">首页</a><a href="/about" className="navbar-mobile-link">关于</a><a href="/contact" className="navbar-mobile-link">联系</a></div>)}</nav>);
}export default NavBar;
特点:
- 无需接收外部参数(
props
),所有逻辑和样式在组件内部定义。 - 可包含内部状态(如
isMenuOpen
控制移动端菜单)。 - 使用
className
定义样式类(而非 HTML 中的class
)。
二、React 中 class
与 className
的区别
这是 React 与 HTML 最基础的语法差异之一,核心原因与 JavaScript 语法冲突有关:
场景 | HTML 中 | React(JSX)中 | 原因 |
---|---|---|---|
定义样式类 | <div class="box"> | <div className="box"> | 在 JavaScript 中,class 是关键字(用于定义类,如 class Person {} ),JSX 基于 JavaScript 语法,因此用 className 替代,避免语法冲突。 |
作用 | 完全一致 | 完全一致 | 都是为元素指定 CSS 样式类,最终渲染到页面时,React 会自动将 className 转换为 HTML 的 class 属性。 |
错误与正确示例:
jsx
// 错误:JSX 中使用 class 会报错
<div class="navbar">导航栏</div>// 正确:使用 className
<div className="navbar">导航栏</div>
三、React 中类名(className)的命名规范
虽然 React 没有强制要求类名格式,但社区通常遵循以下规范,目的是提高代码可读性、维护性,与组件逻辑对应:
1. 以组件名开头(核心规范)
类名通常以组件名作为前缀,明确该样式属于哪个组件,避免样式冲突(尤其在大型项目中)。
示例:
jsx
// 组件名为 NavBar,类名以 navbar- 开头
<nav className="navbar"><div className="navbar-logo">...</div><div className="navbar-links">...</div><button className="navbar-toggle">...</button>
</nav>
2. 小写字母 + 连字符(kebab-case)
React 中类名推荐使用小写字母 + 连字符(如 navbar-link
),与 CSS 样式表中的类名命名习惯一致(CSS 不区分大小写,但连字符更易读)。
3. 语义化命名
类名应描述元素的功能或位置,而非样式本身(如 navbar-active
表示 “导航栏激活状态”,而非 red-text
)。
4. 与 CSS 模块或 CSS-in-JS 配合
在大型项目中,常使用 CSS 模块或 styled-components 等方案,自动生成唯一类名(如 navbar__logo_123
),彻底避免冲突,但基础命名逻辑仍遵循上述规范。
四、总结
- NavBar 组件:无 props 时,内部实现导航逻辑,可包含状态(如菜单切换)。
- className 替代 class:因 JavaScript 关键字冲突,React 中必须用
className
定义样式类。 - 类名命名规范:以组件名开头(如
navbar-xxx
)、小写连字符、语义化,目的是提高可读性和避免冲突。
遵循这些规范能让 React 代码更符合社区习惯,便于团队协作和后期维护。
2 CSS 中变量与固定值的区别
Q:padding: var(--s) var(--m)和直接写8px 16px有什么区别吗,呈现都是一样的,为什么要这样写?
A:
在 CSS 中使用padding: var(--s) var(--m)
和直接写padding: 8px 16px
虽然在特定时刻可能呈现相同的视觉效果,但它们在代码维护、扩展性和设计一致性方面有本质区别。
主要区别如下:
可维护性:
- 使用 CSS 变量(
var(--s)
、var(--m)
)时,只需在一个地方定义这些变量的值(通常在:root
选择器中),就能全局生效。如果需要调整间距,只需修改一处即可,无需逐个查找所有使用该值的地方。 - 直接写固定值(
8px 16px
)时,若要统一调整间距,需要修改所有相关样式,容易遗漏。
- 使用 CSS 变量(
设计系统一致性:
- CSS 变量可以建立一套统一的设计语言,例如
--s
代表小间距,--m
代表中间距,确保整个项目的间距、颜色等保持一致。 - 直接使用固定值容易出现随意定义的情况(比如有时用 8px,有时用 10px),导致设计风格不统一。
- CSS 变量可以建立一套统一的设计语言,例如
灵活性与扩展性:
- 变量可以根据不同场景动态改变,例如通过媒体查询在移动端和桌面端使用不同的变量值:
css
:root {--s: 8px;--m: 16px; }@media (max-width: 768px) {:root {--s: 4px;--m: 8px;} }
- 固定值则需要重复编写媒体查询中的样式,代码冗余。
- 变量可以根据不同场景动态改变,例如通过媒体查询在移动端和桌面端使用不同的变量值:
语义化:
- 变量名(如
--s
、--m
或更具描述性的--spacing-small
、--spacing-medium
)能传达更多语义信息,让代码更易理解。 - 单纯的数值无法体现其用途和含义。
- 变量名(如
总结来说,直接写固定值适合用于简单场景或一次性样式,而使用 CSS 变量更适合中大型项目或需要长期维护的代码,能显著提升开发效率和代码质量。
Q:我觉得类似于编程语言里面的constant全局变量,宏定义这种?
A:
你的理解非常准确!CSS 变量(Custom Properties)确实和编程语言中的常量(constant)、宏定义(macro) 概念高度相似,都是为了实现 “一处定义、多处复用” 的目标。
具体来说:
与常量(constant)的相似性:
- 都需要先定义一个值(如
--spacing-small: 8px
或const SPACING_SMALL = 8
) - 都可以在多处引用,避免重复写具体值
- 修改时只需改定义处,所有引用都会同步更新
- 都需要先定义一个值(如
与宏定义的相似性:
- 都可以看作是 “值的替换机制”(虽然 CSS 变量的工作方式更动态)
- 都能提升代码的一致性,减少 “魔法数字”(无意义的固定值)
不过 CSS 变量比传统常量更灵活的一点是:它可以动态修改(比如通过 JavaScript 或媒体查询实时改变),而编程语言中的常量通常是编译期确定后就不能再改的。这让 CSS 变量在响应式设计、主题切换等场景中更具优势。
这种 “抽象复用” 的思想在编程和样式设计中是共通的,本质上都是为了提高代码的可维护性和扩展性。
3 React 中如何给组件添加状态(state)
How do we add state to a component?
核心方法:使用 useState
钩子
useState
是 React 提供的一个特殊函数(称为 “钩子”),专门用来在函数组件中添加状态。状态可以理解为组件内部需要 “记住” 的数据,当这些数据变化时,组件会重新渲染以展示最新内容。
具体步骤:
导入
useState
首先需要从 React 中导入它:jsx
import { useState } from 'react';
声明状态变量
在组件内部用以下格式声明:jsx
const [状态变量名, 更新函数] = useState(初始值);
- 例子:声明一个记录数量的状态
jsx
const [count, setCount] = useState(0);
count
:状态变量,保存当前的值(初始是 0)setCount
:专门用来更新count
的函数(命名通常是set + 变量名
)useState(0)
:初始化状态,这里初始值是 0
- 例子:声明一个记录数量的状态
使用和更新状态
- 在组件中直接用
{状态变量名}
显示值 - 用
更新函数(新值)
来修改状态(不能直接给状态变量赋值,比如count = 1
是错误的)
完整示例:
jsx
import { useState } from 'react';function Counter() {// 声明一个计数状态,初始值为 0const [count, setCount] = useState(0);return (<div><p>当前计数:{count}</p>{/* 点击按钮时,调用 setCount 更新状态 */}<button onClick={() => setCount(count + 1)}>加 1</button></div>); }
- 在组件中直接用
关键点:
- 每次调用
setCount
(更新函数)后,组件会重新渲染,页面上的count
会显示最新值 - 一个组件可以有多个状态,比如同时声明
[name, setName]
、[age, setAge]
等 - 初始值可以是任意类型(数字、字符串、数组、对象等)
简单说,useState
就像给组件装了一个 “记忆本”,让组件能记住数据的变化,并自动刷新页面展示最新内容,这是 React 实现交互功能的基础。