React基础:JSX语法与组件属性, JSX 简明入门教学指南

 

React基础:JSX语法与组件属性, JSX 简明入门教学指南
React基础:JSX语法与组件属性, JSX 简明入门教学指南

 

JSX是React的核心组成部分,它使用XML标记的方式去直接声明界面,界面组件之间可以互相嵌套。可以理解为在JS中编写与XML类似的语言,一种定义带属性树结构(DOM结构)的语法,它的目的不是要在浏览器或者引擎中实现,它的目的是通过各种编译器将这些标记编译成标准的JS语言。

虽然你可以完全不使用JSX语法,只使用JS语法,但还是推荐使用JSX,可以定义包含属性的树状结构的语法,类似HTML标签那样的使用,而且更便于代码的阅读。

使用JSX语法后,你必须要引入babel的JSX解析器,把JSX转化成JS语法,这个工作会由babel自动完成。同时引入babel后,你就可以使用新的es6语法,babel会帮你把es6语法转化成es5语法,兼容更多的浏览器。

 

所以,如果您的没有node或者其他可以解析JSX的服务器支持,那么您就必须引入 babel 文件才可以使用 JSX 的语法,但是引入这个文件,会使您的网页加载变慢!

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel" src="yourScript.js"></script>

或者:

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
<!-- your script -->
</script>

 

React 使用 JSX 来替代常规的JavaScript

JSX 是按照 XML 语法规范 的 JavaScript 语法扩展。

JSX 有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化;
  • 它是类型安全的,在编译过程中就能发现错误;
  • 使用 JSX 编写模板更加简单快速。

**JSX 语法的本质:**并不是直接把 JSX 渲染到页面上,而是内部先转换成了 createElement 形式,再渲染的。

**JSX 注释:**推荐使用 {/* 这是注释 */}

**JSX中添加class类名:**需要使用 className 来替代 classhtmlFor 替代 labelfor 属性;

JSX创建DOM的时候,所有节点必须有唯一的根元素进行包裹;

JSX语法中,标签必须成对出现,如果是单标签,则必须自闭和;

 

考虑一下这个变量的声明:

const element = <h1>Hello, world!</h1>;

这种有趣的标签语法既不是字符串也不是HTML。

 

这就是 JSX ,他是 JavaScrip 的一种扩展语法。我们推荐在 React 中使用这种语法来描述 UI 信息。JSX 可能会让你想起某种模板语言,但是它具有 JavaScrip 的全部能力。

JSX 可以生成 React “元素”,也可以渲染到DOM上。

 

我们假设你的 HTML 文件中的什么地方有这么一个<div>

<div id="root"></div>

我们称这个是一个 “root” DOM 节点,因为该节点内的所有内容都由 React DOM 管理。

单纯用 React 构建的应用程序通常只有一个单独的 根 DOM 节点。但如果你要把 React 整合进现有的 app 中 ,那你可能会有多个相互独立的 root DOM节点。

要渲染一个 React 元素到一个 root DOM 节点,把它们传递给 ReactDOM.render() 方法:

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

上面代码会在页面上显示 “Hello, world” 。

Try it on CodePen

 

React 元素是 不可突变(immutable) 的. 一旦你创建了一个元素, 就不能再修改其子元素或任何属性。一个元素就像电影里的一帧: 它表示在某一特定时间点的 UI 。

就我们所知, 更新 UI 的唯一方法是创建一个新的元素, 并将其传入 ReactDOM.render() 方法.

思考以下时钟例子:

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);

Try it on CodePen

以上代码每隔 1 秒, 就会通过 setInterval() 回调 ReactDOM.render() 方法来重新渲染元素。

注意:

实际上,大多数 React 应用只会调用 ReactDOM.render() 一次。

 

React DOM 会将元素及其子元素与之前版本逐一对比, 并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态。

你可以用浏览器工具对 上一个例子 进行检查来验证这一点:

DOM 检查器显示颗粒状的更新

即使我们我们每隔 1 秒都重建了整个元素, 但实际上 React DOM 只更新了修改过的文本节点.

在我们的经验中, 关注每个时间点UI的表现, 而不是关注随着时间不断更新UI的状态, 可以减少很多奇怪的 bug 。

下面你可以找到 JSX 的基础知识,以帮助您开始使用。

 

为什么选择JSX?

React 拥抱渲染逻辑与其他 UI 逻辑固有耦合的事实:事件如何处理,状态如何随时间变化以及数据如何准备显示。

通过将标签和逻辑放在单独的文件中,而不是人为分离 技术 ,伴有松散耦合单元的 React 关注点分离 称为“组件(components)”。 我们将在组件(Components) 和 属性(Props) 中详细说明组件 , 但如果你不习惯在 JS 中添加标签,这篇演讲可能会说服你。

React 不强制你使用JSX ,但大多数人发现它在 JavaScript 代码中使用 UI 时作为视觉辅助工具很有帮助。 它还允许 React 显示更多有用的错误和警告消息。

就这样,让我们开始吧!

 

在JSX中嵌入表达式

在下面的例子中,我们声明了一个名为 name 的变量,然后在 JSX 中使用 花括号 将其括起来:

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);

 

你可以用 花括号 把任意的 JavaScript 表达式 嵌入到 JSX 中。例如,2 + 2, user.firstName, 和 formatName(user),这些都是可用的表达式。

在下面的例子中,我们将调用 JavaScript 函数 formatName(user) 的结果嵌入到 <h1> 元素中。

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

Try it on CodePen

为便于阅读,我们将 JSX 分割成多行。我们推荐使用括号将 JSX 包裹起来,虽然这不是必须的,但这样做可以避免分号自动插入的陷阱。

 

JSX 也是一个表达式

编译之后,JSX 表达式就变成了常规的 JavaScript 对象。

这意味着你可以在 if 语句或者是 for 循环中使用 JSX,用它给变量赋值,当做参数接收,或者作为函数的返回值:

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

 

用 JSX 指定属性值

您可以使用双引号来指定字符串字面量作为属性值:

const element = <div tabIndex="0"></div>;

 

您也可以用花括号嵌入一个 JavaScript 表达式作为属性值:

const element = <img src={user.avatarUrl}></img>;

在属性中嵌入 JavaScript 表达式时,不要使用引号将花括号括起来。您应该使用引号(用于字符串值)或大括号(用于表达式),但不能同时使用同一个属性。

 

警告:

由于 JSX 比 HTML 更接近 JavaScript ,因此 React DOM 使用 camelCase 属性命名约定而不是 HTML 属性名称。

例如,在 JSX 中,class 变成了 classNametabindex 变成了 tabIndex

 

用 JSX 指定子元素

如果是空标签,您应该像 XML 一样,使用 />立即闭合它:

const element = <img src={user.avatarUrl} />;

 

JSX 标签可能包含子元素:

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

 

JSX 防止注入攻击

在JSX中嵌入用户输入是安全的:

const title = response.potentiallyMaliciousInput;
// 这样是安全的:
const element = <h1>{title}</h1>;

 

默认情况下, 在渲染之前, React DOM 会格式化(escapes) JSX中的所有值. 从而保证用户无法注入任何应用之外的代码. 在被渲染之前,所有的数据都被转义成为了字符串处理。 以避免 XSS(跨站脚本) 攻击。

 

JSX 表示对象

Babel 将JSX编译成 React.createElement() 调用。

下面的两个例子是是完全相同的:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.createElement() 会执行一些检查来帮助你编写没有bug的代码,但基本上它会创建一个如下所示的对象:

// 注意: 这是简化的结构
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

 

这些对象被称作“React元素”。你可以把他们想象成为你想在屏幕上显示内容的一种描述。React会读取这些对象,用他们来构建DOM,并且保持它们的不断更新。

我们将在下一节中来探索如何将 React 元素渲染到 DOM 上。

 

提示:

我们建议你的编辑器使用 “Babel”语言定义 ,以便正确高亮显示 ES6 和 JSX 代码。

 

 

本文:React基础:JSX语法与组件属性, JSX 简明入门教学指南

Leave a Reply