React 如何进行UI描述 以及React的JSX语法规则

167 阅读4分钟

构建UI:组件

由具有独立UI片段的组件构建,这种组件可以当成是是程序中可以复用的UI元素。这种可复用UI组件是react的一大特点。
组件本质:是可以添加标签的JavaScript函数,以及可以用CSS为其添加样式。
拿到一个需要构建的片段,可以用划分组件的方式去思考,如何通过一个个的组件构建页面。 例如:

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

image.png

如上三张图片,分别为三个组件。构成了所要创建的页面。

构建组件的方法

如上所述,react的组件是可以添加标签的JavaScript函数,这是JSX语法。

  • 第一步,先定义函数。
function Profile() {
}

!提示:虽然是定义函数,但注意定义的是React组件,组件名称必须用大写字母开头,否则无法运行。

  • 第二步:在函数内添加标签,用return返回。
return ( <img src="转存失败,建议直接上传图片文件 https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson转存失败,建议直接上传图片文件">
);

注意写法:如果标签和return关键字不在同一行,则必须包裹在一对括号中,因为return下一行的代码会被忽略。在同一行可以不写括号。

  • 第三步:导出组件 export default前缀是一种JavaScript标准语法(非React本身特性),导出文件主要函数,其他文件便可引用它。
function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

注意:虽然多个组件可以保存在同一份文件中,但是不要嵌套定义组件。

export default function Forward() {
// 错误,不要在组件中定义组件
   function Inner() {
   }
}

导入和导出一个组件步骤:
1.创建一个新的JS文件,后缀名是.js
2.导出文件中的函数组件(默认导出或具名导出)
3.需要使用函数组件的时候导入(默认导入或具名导入)

举例:

import imp from './imp.js';

export default function App() {
  return (
    <Gallery />
  );
}
function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>了不起的科学家们</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

注意:在imp.js文件中使用的是默认导出,在app.js中使用的是默认导入,导入imp.js文件。import imp from './imp.js';和import imp from './imp';两种写法均可,前者更符合原生ES模块。

具名导出和默认导出的区别如下显示:

语法导出语句导入语句
默认export default function Button() {}import Button from >'./Button.js'
具名export function Button() {}import {Button} from './Button.js'

!一个文件里有且仅有一个默认导出,可以有任意多个具名导出。

JSX语法规则

  1. 只能返回一个根元素
    需要一个父标签包裹组件中的标签,父标签可以是盒子标签,如<div></div>,也可以是空的<>和</>. 这个空的标签被叫做Fragment。React Fragment允许将自元素分组,而不会在HTML结构中添加额外节点。
<>
<h1>待办事项<h1/>
<ul><ul/>
</>

为什么只能返回一个父元素? JSX语法在运行时,要被转化为JS对象,一个函数不能返回多个对象,除非用数组包装起来。所以需要父元素或者Fragment包裹。

  1. 标签必须闭合
    闭合标签分为自闭标签如,以及闭合标签,如<li> <li/>
  2. 使用驼峰式命名法给大部分属性命名。
    JSX最终转化为JS,JSX属性变成JS对象中的键值对。JS对变量命名有限制,不能包含-符号或者class等等保留字。所以React中大部分HTML和SVG属性都用驼峰式命名法。对于class这样的保留字,要用className代替。

注意:对于aria-*和data-*的属性时用带-符号带HTML格式书写的。

4.使用引号传递字符串,{}动态指定src或alt的值,使用大括号{}编写JavaScript

引号传递字符串:

export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}

用作紧跟在 = 符号后的属性:

export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}

可以作为类似于模版字符串的功能:

export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}

或者是函数调用:

const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'zh-CN',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}
  1. 使用双大括号:描述JSX中的CSS和对象
    传递对象,需要用双大括号包裹对象,比如传递内联样式:双大括号知识包在JSX大括号内的JavaScript对象。
export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}

注意:内联style属性需要用驼峰命名法编写。

<ul style="background-color: black"> 应该写成
<ul style={{ backgroundColor:'black'}}