# [Learn With Agent] JSX & React Components

# 前言

这是Learn With Agent 的第一篇博客，这个系列（不知道有没有后续了）是想通过agent辅助进行快速的学习（过概念）掌握一些相关的知识。之后再通过agent辅助开发，应该也能做出来个7788。对于AI还有很多思考，另起一个博客再说吧就。

因为网络和经费原因，这里使用的是CC+GLM 4.6 & Gemini 系列。🈚️广，文字为百分百人类手敲&传统CV大法。

# JSX

JSX是React生态中占据很重要的部分，JSX是一种语法拓展，它可以允许用户在js中写类似html的标签结构。 JSX还是一种描述UI的方式。对于react component，JSX像是镜像，而react component更像容器，它的作用就是将JSX渲染成真实的DOM。

```js
// 1. 这是一个 React 组件（函数）
function Welcome(props) {
  // 2. 组件在它的 return 语句中使用了 JSX
  return (
    // 这是 JSX，它描述了一个 <h1> 和一个 <p> 标签的 UI 结构
    <div>
      <h1>Hello, {props.name}!</h1>
      <p>这是 Welcome 组件的内容。</p>
    </div>
  );
  // 3. 这个 JSX 最终会被组件返回
}
```

# JSX 渲染机制

## bundle.js 文件

JSX 本质上是 JavaScript 的一个扩展语法。浏览器或 Node.js 环境（在没有额外配置的情况下）并不能直接识别

这样的 JSX 标签。因此，它们必须被转换成普通的 JavaScript 代码。 如果是一个简单的在线demo，比如从cdn中直接引入babel，它会实时运行，并且把jsx转换为React.createElement调用。 在一个CICD流水线中，会通过webpack、vite等工具将所有jsx转换为浏览器可以识别的bundle.js 文件。这个bundle.js文件中已经不含任何 JSX 语法了。

## 运行时渲染&虚拟dom

转译后的代码进入浏览器后，React库本身会接管整个渲染过程。 React.createElement 调用不会直接生成DOM元素，而是返回一个轻量级的JavaScript对象，我们称之为React元素（React Element）。 主要是因为浏览器操作真实dom会有昂贵的开销，所以说React引入了虚拟dom的概念。 虚拟dom是一个轻量级的JavaScript对象，它描述了真实dom的结构。当组件的状态发生变化时，React会重新渲染组件，并且对比前后两次渲染的虚拟dom差异，只更新必要的部分到真实dom中。它存在的唯一目的就是为了提高性能，尤其是在需要频繁更新UI的应用中。

# Components

## react中组件的作用

react中组件的主要作用就是封装ui以及交互逻辑。和后端的microservices很像，组件的主要作用除了用就是为了复用 :)

一个简单的组件的例子：

```js
    const Avatar = ({ imageUrl, name }) => {
      return (
        <div className="grandchild-component">
          <h5>📸 头像组件 (组件)</h5>
          <img
            src={imageUrl || `https://picsum.photos/seed/${name}/50/50.jpg`}
            alt={`${name}的头像`}
            style={{width: '50px', height: '50px', borderRadius: '50%'}}
          />
        </div>
      );
    };
```

一个页面往往由多个组件构成，这也是前端工程化组件化的思想之一

```js
  const App = () => {       
    return (           
      <div>                    
        <BasicJSXDemo />      // 独立的功能组件
        <ComparisonDemo />    // 独立的对比演示组件 
        <DynamicDataDemo />   // 独立的数据展示组件                                 
        <InteractiveDemo />   // 独立的交互演示组件                                 
      div>                                                                       
    );                                                                           
  };
```

## 父子组件

父子组件顾名思义

来拿我们后端的内容做对比的话：

组件层级 ≈ 容器编排层级 (K8s: Pod → Service → Deployment)         

Props传递 ≈ 配置传递 (ConfigMap → Pod)                                                                                       

事件回调 ≈ 事件通知 (Webhook/Alert Manager)                                                                                

组件复用 ≈ 模板复用 (Terraform/Helm Chart)

### 父子组件的实际应用

父子组件关系就像现实中的父子关系一样，父组件负责管理和协调，子组件负责具体的业务逻辑实现。

React中，数据是单向流动的，从父组件流向子组件，这个设计模式被称为"单向数据流"。这样可以避免数据管理的混乱，让组件之间的依赖关系更加清晰。

```js
// 父组件
const UserProfile = () => {
  const [userName, setUserName] = useState("张三");
  const [userAge, setUserAge] = useState(25);

  // 父组件定义的事件处理函数
  const handleAgeChange = (newAge) => {
    setUserAge(newAge);
  };

  return (
    <div className="parent-component">
      <h3>用户资料</h3>
      {/* 通过props将数据传递给子组件 */}
      <UserAvatar
        name={userName}
        age={userAge}
        onAgeChange={handleAgeChange}  // 将回调函数传递给子组件
      />
    </div>
  );
};

// 子组件
const UserAvatar = ({ name, age, onAgeChange }) => {
  const handleClick = () => {
    // 子组件调用父组件传递的回调函数
    onAgeChange(age + 1);
  };

  return (
    <div className="child-component">
      <h4>头像：{name}</h4>
      <p>年龄：{age}</p>
      <button onClick={handleClick}>增加年龄</button>
    </div>
  );
};
```

通过合理地使用父子组件的结构，可以构建出更加清晰、可维护的react project。
