xChar

什么是 JSX?

JSX 是js的语法扩展,允许在js中编写html代码, 是 2013 年 伴随 React 库的首次发布而出现,并简化了用户界面的开发过程和提高代码的可读性及维护性

例如🌰

// 不使用 JSX 的 React 代码
const element = React.createElement('h1', { className: 'title' }, 'Hello, world!');

// 使用 JSX 的 React 代码
const element = <h1 className="title">Hello, world!</h1>;

[!TIP]
JSX 比 HTML 更加严格。你必须闭合标签,如 <br />。你的组件也不能返回多个 JSX 标签。你必须将它们包裹到一个共享的父级中,比如 <div>...</div> 或使用空的 <>...</> 包裹:

function Hello() {
  return (
    <>
      <h1>Hello, world!</h1>
    </>
  );
}

在 JSX 中嵌入表达式

const name = '张三';
const fn = () => alert('fn函数')

const App = () => {
  return (
    <>
      <h1>{ name }</h1>
      <button>{ fn() }</button>
      <p>{ new Date().toLocaleString() }</p>
    </>
  );
};

在 JSX 中添加属性

[!WARNING]
由于 JSX 比 HTML 更接近 JavaScript,因此 React DOM 使用驼峰式属性命名约定而不是 HTML 属性名称。
例如,class 在 JSX 中变为 classNametabindex 变为 tabIndex。

const user = {
  className: 'avatar-img',
  imageUrl: 'https://www.gravatar.com/avatar/0?d=mp',
  style: {
    border: '2px solid red',
    borderRadius: '50%',
  }
}

const App = () => {
  return (
    <>
      <img src={ user.imageUrl } className={ user.className } style={user.style} alt="Avatar" />
    </>
  );
};

在 JSX 中绑定事件

使用tsx绑定事件 on[Click]{ fn } 小驼峰 其他事件也是一样的。如果需要传递参数可以使用 on[Click]{ () => fn() }

const clickFn = (name) => {
  console.log('clicked', name);
}
const mouseEnterFn = () => {
  console.log('mouse entered');
}
const mouseLeaveFn = () => {
  console.log('mouse leveled');
}

const App = () => {
  return (
    <>
      <h1>Hello, world!</h1>
      <button onClick={() => clickFn('button')} onMouseEnter={mouseEnterFn} onMouseLeave={mouseLeaveFn}>Click me</button>
    </>
  );
};

在 JSX 中条件渲染

const flag = true;

const App = () => {
  return (
    <>
      <div>{ flag ? <div>真的</div> : <div>假的</div> }</div>
    </>
  );
};

当你不需要 else 分支时,你也可以使用更简短的 逻辑 && 语法:

<div>
  {isLoggedIn && <AdminPanel />}
</div>

更复杂的判断逻辑可以写在一个函数里面

const messageTip = (code) => {
  switch (code) {
    case 200:
      return <div className="message-tip success">Success</div>;
    case 404:
      return <div className="message-tip error">Error</div>;
    default:
      return <div className="message-tip info">Info</div>;

  }
}
const App = () => {
  return (
    <>
      { messageTip(200) }
    </>
  );
};

在 JSX 中遍历元素

使用map遍历返回 html 标签

const userList = [
  { id: 1, name: '张三', age: 18, gender: '男' },
  { id: 2, name: '李四', age: 19, gender: '女' },
  { id: 3, name: '王五', age: 20, gender: '男' },
  { id: 4, name: '赵六', age: 21, gender: '女' },
  { id: 5, name: '钱七', age: 22, gender: '男' },
  { id: 6, name: '孙八', age: 23, gender: '女' },
  { id: 7, name: '周九', age: 24, gender: '男'},
]
const App = () => {
  return (
    <>
      { userList.filter(user => user.age > 20).map(user => <div key={user.id}>{user.name}</div>) }
    </>
  );
};

在 JSX 中渲染 html片段

[!WARNING]
使用 dangerouslySetInnerHTML 后元素不要添加内容,否则会出粗

const App = () => {
  return (
    <>
      <div dangerouslySetInnerHTML={{__html: el}}>{/* 此处留空,否则会报错 */}</div>
    </>
  );
};

常见问题

1、JSX 语句内只能使用表达式、不能使用语句和字面量等

// Error: Objects are not valid as a React child (found: object with keys {key}). If you meant to render a collection of children, use an array instead.
const element = <div>{ { key: 'value' } }</div>;

// ✅
const element = <div>{ JSON.stringify({ key: 'value' }) }</div>;

// ✅
const element = <div>{ { key: 'value' }.key }</div>;

2、TSX 如何使用泛型
正常写泛型语法会跟tsx语法冲突,他会把泛型理解成是一个元素,解决方案后面加一个 , 即可

const clickTap = <T,>(params: T) => alert(params)
const element = <button onClick={() => clickTap('张三')}>Click me</button>;
Loading comments...