当前位置: 首页 > article >正文

nodejs 019: React组件 JSX基础语法规则

  • 注:本文为JSX基础语法规则总结,除一二级标题外的大部分内容由LLM生成
  • JSX(JavaScript XML)是一种语法扩展,主要用于 React 项目。它让我们可以在 JavaScript 中直接编写类似 HTML 的代码,简化了定义 UI 组件的过程( JSX有点像JAVA的JSP)。
  • JSX 将标记和逻辑紧密结合,使代码更具可读性和可维护性。JSX 是一个由 React 引入的概念,现在在其他框架(如 Vue 3)中也得到了应用。

Ⅰ.JSX 的基本概念

  1. 类似 HTML 的语法

    const element = <h1>Hello, world!</h1>;
    
  2. 在组件中使用 JSX
    JSX 最常用于定义 React 组件的结构。React 组件是一个返回 JSX 的函数或类,可以将复杂的 UI 拆分成独立、可复用的组件。例如:

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    

JSX 的特点和优势

  • 内嵌表达式:在 JSX 中可以嵌入任何 JavaScript 表达式,只需将其包裹在 {} 中。

    const name = 'React';
    const element = <h1>Hello, {name}</h1>;
    
  • 支持条件渲染:可以使用 JavaScript 的条件运算符进行条件渲染。

    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      return (
        <div>
          {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}
        </div>
      );
    }
    
  • 支持循环渲染:可以通过 map 等方法来渲染列表。

    const numbers = [1, 2, 3, 4, 5];
    const listItems = numbers.map((number) =>
      <li key={number.toString()}>{number}</li>
    );
    
    return <ul>{listItems}</ul>;
    

Ⅱ.className

  • className 是 JSX 中用于指定 HTML 元素 CSS 类的属性。在标准的 HTML 中,我们使用 class 属性来指定样式,但在 JSX 中,因为 class 是 JavaScript 的保留字,所以改成了 className

  • 在 JSX 中设置 className 非常简单,类似于 HTML 的 class,只需在元素上添加 className 属性并赋值一个字符串即可:

function MyComponent() {
  return <div className="my-class">Hello, World!</div>;
}
  • 动态设置 className ;

    1. 三元运算符

使用三元运算符来根据条件设置 className

function MyComponent({ isActive }) {
  return <div className={isActive ? "active" : "inactive"}>Hello, World!</div>;
}
    1. 模板字符串

如果需要组合多个类,可以使用模板字符串(ES6 的字符串模板语法):

function MyComponent({ isActive, isLarge }) {
  return <div className={`${isActive ? "active" : ""} ${isLarge ? "large" : ""}`}>Hello, World!</div>;
}
    1. 使用条件库 classnames

在大型项目中管理多个条件类时,可以使用 classnames 库。它简化了 className 的管理,让代码更加清晰易读:

npm install classnames

使用示例:

import classNames from 'classnames';

function MyComponent({ isActive, isLarge }) {
  const classes = classNames({
    active: isActive,
    large: isLarge,
    'extra-class': true,
  });

  return <div className={classes}>Hello, World!</div>;
}

在上面的代码中,classnames 自动生成类名字符串。如果 isActiveisLargetrue,生成的 className 会是 active large extra-class

通过样式文件使用 className

通常,我们会在组件中用 className 连接 CSS 样式表,方法是将样式写在 CSS 文件中,然后通过 className 引用。

使用 CSS 模块

在 React 中也可以使用 CSS 模块,这样可以避免样式的全局污染。CSS 模块会自动生成独特的类名,以保证样式只在当前组件中有效。

  • 首先,创建一个 CSS 模块文件,比如 MyComponent.module.css

    /* MyComponent.module.css */
    .active {
      color: red;
    }
    
    .large {
      font-size: 2em;
    }
    
  • 在组件中导入这个 CSS 模块并应用样式:

    import styles from './MyComponent.module.css';
    
    function MyComponent({ isActive, isLarge }) {
      return (
        <div className={`${isActive ? styles.active : ""} ${isLarge ? styles.large : ""}`}>
          Hello, World!
        </div>
      );
    }
    

使用 className,可以轻松地将 CSS 应用到 JSX 元素中,并且能动态地控制它们。

Ⅲ.首字母大小写和自定义组件

在 React 中,组件的命名约定非常重要,尤其是当涉及到首字母大小写的使用和自定义组件的区分时。以下是相关的细节:

1. 首字母大小写的规则

React 通过组件名称的首字母大小写来区分 HTML 元素和自定义 React 组件:

  • 首字母大写:React 认为这是一个自定义组件。自定义组件通常是函数或类,并且在 JSX 中渲染时,React 会调用它返回的 JSX 结构。例如,<MyComponent /> 被认为是一个 React 组件。

    function MyComponent() {
      return <div>Hello from MyComponent!</div>;
    }
    
    function App() {
      return <MyComponent />;
    }
    
  • 首字母小写:React 会将其当作标准 HTML 元素(如 <div><span>)来渲染。如果在 JSX 中写 <mycomponent />,React 会尝试将其当作 HTML 标签而不是组件,导致渲染失败或产生警告。

2. 自定义组件的编写

在 React 中编写自定义组件时,我们通常遵循 PascalCase(即每个单词的首字母大写)命名规范,这样可以避免和 HTML 标签冲突,并符合 React 社区的常规习惯。例如:

function UserProfile() {
  return <div>User Profile Component</div>;
}

使用自定义组件时可以传递 props

function UserProfile({ name }) {
  return <div>Hello, {name}!</div>;
}

function App() {
  return <UserProfile name="Alice" />;
}

3. 动态渲染自定义组件

有时,我们可能需要动态选择组件进行渲染。可以通过对象映射来实现动态组件的选择,例如:

function Home() {
  return <div>Home Component</div>;
}

function About() {
  return <div>About Component</div>;
}

const components = {
  home: Home,
  about: About,
};

function App({ componentName }) {
  const Component = components[componentName];
  return Component ? <Component /> : <div>Component Not Found</div>;
}

// 使用示例
<App componentName="home" />; // 渲染 Home 组件

4. 使用小写首字母的自定义标签(非 React 推荐)

尽管不推荐,但在某些情况下可能需要使用小写的自定义标签。可以通过直接创建元素来实现。React 提供了 React.createElement 函数,可以用来创建 React 元素而不依赖 JSX。例如:

function app() {
  return React.createElement("custom-element", { id: "myId" }, "Hello!");
}

不过,为了遵循 React 社区的最佳实践,尽量避免这种方式。

5. CSS 组件样式约定

对于自定义组件的样式,可以使用对应的 className,配合 CSS 文件或者 CSS 模块。CSS 模块可以使样式在组件间隔离,避免样式冲突。

// MyComponent.module.css
.myComponent {
  color: blue;
}

// MyComponent.jsx
import styles from './MyComponent.module.css';

function MyComponent() {
  return <div className={styles.myComponent}>Styled Component</div>;
}

总结

  • 自定义组件的名称应始终以大写字母开头,以便 React 能够正确识别它们。
  • 可以使用 props 为组件传递数据,保持组件的可复用性。
  • 动态选择和渲染自定义组件时,可以用对象映射来选择特定组件。
  • 使用 CSS 模块或 className 控制组件样式,保持组件之间的样式隔离。

Ⅳ.style要写成对象的形式

在 JSX 中,style 属性需要写成 JavaScript 对象的形式,而不是普通的字符串或 CSS 样式规则。每个 CSS 属性都需要用 JavaScript 对象的语法表示。

基本写法

在 React 中使用 style 属性时,应该使用 驼峰命名(camelCase),因为在 JavaScript 中 - 是无效字符。

例如,background-color 需要写成 backgroundColor

function MyComponent() {
  return (
    <div style={{ backgroundColor: 'blue', color: 'white', padding: '10px' }}>
      Hello, World!
    </div>
  );
}

上面的 style 属性接收一个 JavaScript 对象,其中每个 CSS 属性都以键值对的形式表示。

动态设置样式

你可以在 style 对象中动态设置样式属性,通过变量或者表达式来实现。例如,可以根据组件的状态改变样式:

function MyComponent({ isActive }) {
  return (
    <div
      style={{
        color: isActive ? 'green' : 'gray',
        fontWeight: isActive ? 'bold' : 'normal',
      }}
    >
      Status: {isActive ? 'Active' : 'Inactive'}
    </div>
  );
}

多个样式对象的组合

如果有多个样式对象,可以通过 JavaScript 的扩展运算符 {...}Object.assign 合并样式:

const baseStyle = {
  color: 'white',
  fontSize: '16px',
};

const activeStyle = {
  color: 'green',
  fontWeight: 'bold',
};

function MyComponent({ isActive }) {
  return (
    <div style={{ ...baseStyle, ...(isActive ? activeStyle : {}) }}>
      Hello, World!
    </div>
  );
}

示例:样式对象与内联样式

const containerStyle = {
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  height: '100vh',
  backgroundColor: '#282c34',
};

function App() {
  return (
    <div style={containerStyle}>
      <h1 style={{ color: 'white', fontSize: '2em' }}>Welcome to My App</h1>
    </div>
  );
}

在这个示例中,containerStyle 是一个样式对象,并且在 App 组件中通过 style={containerStyle} 赋给 div 标签;h1 的样式则直接写在内联 style 中。

注意事项

  • 单位:数值型的 CSS 属性(如 width, height, fontSize)通常不需要单位,会自动以像素 (px) 处理。例如:fontSize: 20 表示 20px
  • 嵌套样式:不能在 style 对象中直接嵌套选择器,如 :hover@media,这些需要通过 CSS 文件或 CSS-in-JS 解决方案(如 styled-components)来实现。

使用对象形式的 style 属性可以更灵活地实现样式的动态更新,也能充分利用 JavaScript 的表达能力。

Ⅴ.监听事件

1. 添加事件监听器

  • 在 React 中,事件监听器使用 camelCase 形式,比如 onClickonMouseEnter 等。事件处理函数通常是一个箭头函数或组件方法。

示例:一个按钮的点击事件

function App() {
  function handleClick() {
    console.log("Button clicked!");
  }

  return <button onClick={handleClick}>Click me</button>;
}
  • 注:不要写函数的执行结果

2. 事件对象

React 中的事件处理函数会接收到一个合成事件(SyntheticEvent),它是对原生事件的封装,与原生 DOM 事件 API 类似且跨浏览器兼容。

示例:使用事件对象


function App() {
  function handleClick(event) {
    console.log("Button clicked at position:", event.clientX, event.clientY);
  }

  return <button onClick={handleClick}>Click me</button>;
}

在这个示例中,event.clientXevent.clientY 是点击事件发生的鼠标位置。

3. 使用箭头函数传递参数

如果需要给事件处理函数传递参数,可以使用箭头函数。

示例:传递自定义参数

function App() {
  function handleClick(name) {
    console.log(`Hello, ${name}!`);
  }

  return <button onClick={() => handleClick("Alice")}>Greet Alice</button>;
}

这里我们用箭头函数 () => handleClick("Alice") 将参数传递给 handleClick

4. 事件的常用类型

React 支持大多数常见的 DOM 事件,包括但不限于:

  • 鼠标事件onClick, onDoubleClick, onMouseEnter, onMouseLeave, onMouseMove
  • 键盘事件onKeyDown, onKeyUp, onKeyPress
  • 表单事件onChange, onSubmit, onFocus, onBlur
  • 窗口事件onResize, onScroll
  • 剪贴板事件onCopy, onPaste
import React, { useState } from "react";
import type { MouseEvent } from "react";

function MouseTracker() {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  // 使用 MouseEvent 类型为事件处理函数添加类型定义
  function handleMouseMove(event: MouseEvent<HTMLDivElement>) {
    setPosition({
      x: event.clientX,
      y: event.clientY,
    });
  }

  return (
    <div
      onMouseMove={handleMouseMove}
      style={{
        width: "400px",
        height: "300px",
        border: "2px solid black",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      <p>Mouse Position: ({position.x}, {position.y})</p>
    </div>
  );
}

export default MouseTracker;

5. 阻止默认行为和事件传播

可以通过 event.preventDefault()event.stopPropagation() 控制事件的行为。

示例:阻止表单提交的默认刷新行为

function App() {
  function handleSubmit(event) {
    event.preventDefault();
    console.log("Form submitted!");
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

在这个示例中,通过 event.preventDefault() 阻止了表单的默认提交行为。

6. 事件解绑

在 React 中,通常不需要手动解绑事件。React 的合成事件系统会自动管理事件的绑定和解绑,以确保性能和资源使用。

7. 使用 useEffect 监听全局事件

如果需要监听全局事件(例如 windowdocument 的事件),可以使用 useEffect 钩子在组件挂载时添加事件监听,并在卸载时移除。

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    function handleResize() {
      console.log("Window resized!");
    }

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return <div>Resize the window to see the effect!</div>;
}

在这里,我们使用 useEffect 监听 windowresize 事件,并在组件卸载时清理该事件监听器。

Ⅵ.{}和判断

  • {}中不能放置大段js代码,需要通过&& 和 三目运算符进行条件判断

    错误示例

    // 这会导致错误
    return (
      <div>
        {if (isLoggedIn) { <p>Welcome back!</p> }}
      </div>
    );
    

    正确示例

    let message;
    if (isLoggedIn) {
      message = <p>Welcome back!</p>;
    } else {
      message = <p>Please log in.</p>;
    }
    
    return <div>{message}</div>;
    
使用 && 运算符

&& 运算符通常用来在条件为 true 时渲染内容,否则什么都不显示。

const isLoggedIn = true;
return (
  <div>
    {isLoggedIn && <p>Welcome back!</p>}
  </div>
);

解释

  • 如果 isLoggedIntrue,则渲染 <p>Welcome back!</p>
  • 如果 isLoggedInfalse,则什么也不渲染。
使用三目运算符 ? :

三目运算符允许你根据条件返回不同的内容。

const isLoggedIn = true;
return (
  <div>
    {isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>}
  </div>
);

解释

  • 如果 isLoggedIntrue,则渲染 <p>Welcome back!</p>
  • 如果 isLoggedInfalse,则渲染 <p>Please log in.</p>

通过使用 &&? : 运算符,React 组件能够以简洁的方式实现条件渲染。

Ⅶ.{}和循环

在 React JSX 中,{} 用于嵌入 JavaScript 表达式,但它不能直接包含 for 循环语句,因为 for语句 而不是 表达式。因此,如果想在 React 中循环渲染多个元素,需要使用 JavaScript 的 数组方法(如 map())来实现。

使用 map() 渲染列表

const items = ["Apple", "Banana", "Cherry"];

function ItemList() {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

export default ItemList;

解释

  • 使用 items.map() 遍历 items 数组,并为每个 item 返回一个 <li> 元素。
  • key 属性用于唯一标识每个元素,帮助 React 识别列表中的元素变化,以提高渲染效率。

在组件中使用循环

如果你确实需要使用 for 循环,可以在 JSX 之外创建一个变量来存储结果,并在 JSX 中引用该变量。

const items = ["Apple", "Banana", "Cherry"];

function ItemList() {
  const listItems = [];
  for (let i = 0; i < items.length; i++) {
    listItems.push(<li key={i}>{items[i]}</li>);
  }

  return <ul>{listItems}</ul>;
}

export default ItemList;

解释

  • 先使用 for 循环将 <li> 元素推入 listItems 数组。
  • 然后在 JSX 中使用 {listItems} 渲染列表。

JSX语法注意项目:

  • 属性命名:在 JSX 中,classclassName 替代,forhtmlFor 替代,以避免与 JavaScript 保留字冲突。
// 正确的写法(React JSX)
<label htmlFor="username">Username:</label>
<input id="username" type="text" />

// 错误的写法
<label for="username">Username:</label>
<input id="username" type="text" />
  • JSX 必须封闭标签:如果标签没有内容,必须使用自闭合形式 <br />,否则会报错。
  • 每个JSX片段只能有一个根节点 :
function MyComponent() {
  return (
    <>
      <div>Element 1</div>
      <div>Element 2</div>
    </>
  );
}

http://www.kler.cn/a/389369.html

相关文章:

  • 《EasyQuotation 与MongoDB在股市信息的奇妙融合》
  • react的创建与书写
  • kafka消费数据太慢了,给优化下
  • 【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-最大的数
  • Coggle数据科学 | RAG编码模型对比:谁与OpenAI最为相似?
  • 【Playwright + Python】系列(十)利用 Playwright 完美处理 Dialogs 对话框
  • 【FFmpeg】FFmpeg 函数简介 ③ ( 编解码相关函数 | FFmpeg 源码地址 | FFmpeg 解码器相关 结构体 和 函数 )
  • 管家婆ERP集成金蝶云星空(金蝶云星空主供应链)
  • 苍穹外卖05-Redis相关知识点
  • 简单实用RTC时钟 | 使用手册
  • Ubuntu22.04安装cuDNN
  • 计算机课程管理平台:Spring Boot与工程认证的结合
  • 【Uniapp】Uniapp Android原生插件开发指北
  • [mysql]DDL,DML综合案例,
  • 自动驾驶安全方向论文阅读
  • 【前端基础】Javascript取整函数以及向零取整方式
  • ffmpeg 视频滤镜:屏蔽边框杂色- fillborders
  • C++ : STL容器(适配器)之stack、queue剖析
  • 【Java Web】JSP实现数据传递和保存(中)中文乱码 转发与重定向
  • 探索PyAV:Python中的多媒体处理利器
  • 【网络协议栈】网络层(上)网络层的基本理解、IP协议格式、网络层分组(内附手画分析图 简单易懂)
  • 基于matlab的人民币面额识别
  • redis bind 127.0.0.1和bind 10.34.56.78的区别
  • Hive面试题-- 查询各类型专利 top10 申请人及专利申请数
  • c++基础28函数的类型
  • oracle死锁彻底解决办法