Skip to content

react语法

1. jsx基本语法

1.1 渲染变量

vue的话是,在react中是{}

tsx
const name = "张三";
<div>
  {name}
</div>

1.2 样式的类名

不再使用class,而是className

tsx
const name = "张三";
<div className="active">
  {name}
</div>

插入变量的写法

tsx
// 手动拼接的问题:条件为false时会产生空字符串和多余空格
<div 
    className={
        `container ${isActive ?
            'active' : ''} ${isDisabled ?
            'disabled' : ''}`}
    >
</div>
// 如果isActive和isDisabled都是false,最终类名是 "container  "(多余空格)

需要用到clsx这个工具库

INFO

clsx 是一个轻量级(体积<1KB)、无依赖的 JavaScript 工具库,专门用于在 React(也可用于普通 JS)中条件性地拼接 CSS 类名。它的核心作用是简化 “根据不同条件动态生成类名” 的逻辑,避免手动拼接类名时出现的冗余空格、空字符串等问题,让类名管理更简洁、健壮。

jsx
import clsx from 'clsx';

<span
  className={clsx(  
    isChild ? 'text-sm' : 'font-medium',
    'hover:text-primary',
    'cursor-pointer'
  )}
>
  {goodsInfo.title}
</span>

1.3 内联样式

普通写法

tsx
const name = "张三";
<div className="active" style="{{color:'red'}}">
  {name}
</div>

// 可以写成小驼峰加变量 style={{ backgroundColor: item.bgColor }}

1.4 使用<></>当根标签

简单案例↓

tsx
const name = "张三";
< >
<div className="active" style="{{color:'red'}}">
  {name}
</div>
</ >

复杂案例

如果是一个界面渲染时的判断显示

tsx
{product.isActive && (
  <>
    <span className="text-sm text-black">{product.title}</span>
    <span className="text-sm text-gray">{product.desc}</span>
    <span className="text-sm text-gray">{product.create_time}</span>
  </>
)}

2.组件

2.1 类组件( 早期写法 )

React 16.8 之前的主流写法

tsx
// HelloWorldClass.tsx
import React, { Component } from 'react';

// 类组件:必须继承 React.Component,通过render返回内容
export default class HelloWorldClass extends Component {
  // 核心方法:render是类组件的必备方法,返回可渲染的JSX
  render() {
    return (
      <div style={{ padding: '20px', fontSize: '20px', color: '#666', marginTop: '20px' }}>
        <h1>Hello World(类组件)</h1>
        <p>这是React类组件的基础示例</p>
      </div>
    );
  }
}

2.2 函数组件

这是 React 16.8 + 推荐的写法,语法简洁

tsx
// HelloWorldFunction.tsx
import React from 'react';

// 函数组件:无状态基础版(最简洁的Hello World)
export default function HelloWorldFunction() {
  // 返回JSX(React的模板语法),展示Hello World
  return (
    <div style={{ padding: '20px', fontSize: '20px', color: '#333' }}>
      <h1>Hello World(函数组件)</h1>
      <p>这是React函数组件的基础示例</p>
    </div>
  );
}
  • 函数式组件定义时首字母必须大写
  • render渲染时必须使用标签

3 循环渲染列表

分为forEach渲染和map渲染,这俩也就是js数组方法

3.1 map渲染列表(最常用)

  1. 返回新数组:map 遍历数组时返回包含 JSX 的新数组,可直接嵌入 JSX 中渲染,语法极简;
  2. 纯函数特性:map 不修改原数组,返回新数组,符合 React“无副作用、数据不可变” 的设计理念;
  3. 适配 JSX 语法:JSX 中只能嵌入 “表达式”(变量、函数调用、数组等),map 返回的数组是合法表达式,而 forEach 无返回值(undefined)、filter 返回的是原数组子集(非 JSX),都无法直接满足。
tsx
import React from 'react';

// 极简map渲染:直接返回JSX数组
export default function MapRender() {
  const list = ['Vue', 'React', 'Angular'];
  return (
    <ul>
      {list.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

升级写法包含filter过滤

tsx
import React from 'react';

export default function FilterMapDemo() {
  const list = ['HTML', 'CSS', 'JavaScript', 'React', 'Vue'];
  
  return (
    <ul>
      {/* 第一步:filter筛选出包含"a"的元素;第二步:map渲染筛选后的结果 */}
      {list
        .filter(item => item.includes('a')) // 筛选:返回 ['JavaScript', 'React']
        .map((item, index) => (
          <li key={index}>{item}</li> // 渲染:仅显示这两个元素
        ))
      }
    </ul>
  );
}

高级写法

日常开发基本上就是写这种了

tsx
import React from 'react';

// 保持原有接口定义不变
interface Product {
  id: number;
  name: string;
  price: number;
  isDiscount: boolean;
}

export default function MapWithCondition() {
  const productList: Product[] = [
    { id: 1, name: 'T恤', price: 99, isDiscount: true },
    { id: 2, name: '裤子', price: 199, isDiscount: false },
    { id: 3, name: '鞋子', price: 399, isDiscount: true },
  ];

  return (
    <div className="p-5"> {/* 替换内联padding: '20px' */}
      <h3 className="text-lg font-medium mb-4">商品列表</h3> {/* 标题样式 */}
      {/* map循环核心逻辑不变,仅替换样式类名 */}
      {productList.map((product) => {
        const finalPrice = product.isDiscount ? product.price * 0.8 : product.price;
        let priceTag = '';
        if (finalPrice < 100) {
          priceTag = '平价';
        } else if (finalPrice < 200) {
          priceTag = '中端';
        } else {
          priceTag = '高端';
        }

        return (
          <div
            key={product.id}
            className="p-2.5 my-2 border border-gray-200 rounded-md" // 替换商品卡片内联样式
          >
            <div className="mb-1">商品名称:{product.name}</div>
            <div className="mb-1">原价:¥{product.price}</div>
            <div className="mb-1">
              最终价格:
              {/* 条件判断样式类名:折扣价红色,原价默认黑色 */}
              <span className={product.isDiscount ? 'text-red-600' : 'text-black'}>
                ¥{finalPrice}
              </span>
              {/* 折扣标签:ml-2 对应 marginLeft: '8px' */}
              {product.isDiscount && <span className="ml-2">[8折]</span>}
            </div>
            <div>价格标签:{priceTag}</div>
          </div>
        );
      })}
    </div>
  );
}

INFO

注意,不知道你发现没有,前2个map循环都没写return

为什么这个复杂的写了循环呢?


注意箭头函数 =>{ } 的花括号

tsx
import React from 'react';

export default function ArrowMapDemo() {
  const list = ['React', 'Vue', 'Angular'];

  // 完整写法:带花括号 + return
  const listFull = list.map((item, index) => {
    return <li key={index}>{item}</li>;
  });

  // 简写一行:省略花括号 + 省略 return
  const listShort = list.map((item, index) => <li key={index}>{item}</li>);
  // 正常情况:有多行内容,需要加小括号包含div标签
  const listShort2 = list.map((item, index) => (
  	<li key={index}>{item}</li>
    ...
  ));

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

它在循环体内,可以写变量,但是map循环需要return一个dom出去,花括号是必须的,加小括号是给return识别用的,不然不识别div这些。

3.2 forEach 渲染

注意forEach没有return返回值,直接写成上面那样会报错

这个items就是一个小型的子组件,基本不会去写forEach循环,谁写了要被笑话的

tsx
import React from 'react';

export default function ForEachRender() {
  const list = ['HTML', 'CSS', 'JavaScript'];
  const items = [];
  
  list.forEach((item, index) => {
    items.push(<li key={index}>{item}</li>);
  });

  // 直接渲染收集好的items数组
  return <ul>{items}</ul>;
}

4 组件实例

4.1 类组件class

经典count计数器

tsx
import React, { Component } from 'react';

// Class组件:通过this.state定义状态,this.setState修改状态
export default class ClassStateDemo extends Component {
  // 1. 初始化state(类组件的状态必须放在this.state中)
  state = {
    count: 0, // 计数器初始值为0
  };

  // 2. 定义修改状态的方法(必须用箭头函数避免this指向问题)
  increment = () => {
    // 类组件必须用this.setState修改状态(不能直接赋值this.state.count++)
    this.setState({ count: this.state.count + 1 });
  };

  decrement = () => {
    this.setState({ count: this.state.count - 1 });
  };

  // 3. 渲染UI,通过this.state获取状态
  render() {
    return (
      <div style={{ padding: '20px' }}>
        <h3>Class组件 - 计数器</h3>
        <p>当前计数:{this.state.count}</p>
        <button onClick={this.increment} style={{ marginRight: '8px' }}>加1</button>
        <button onClick={this.decrement}>减1</button>
      </div>
    );
  }
}

Released under the MIT License.