React - JSX语法指南

本文详细介绍了JSX的概念及其在React中的应用。JSX是一种类似于XML的语法扩展,用于更直观地描述UI界面。文章还探讨了JSX的陷阱及如何正确使用属性扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是JSX

JSX==JavaScriptXML,是React的核心组成部分,它使用XML标记的方式去直接声明界面,界面组件之间可以互相嵌套。
JSX 可以理解为在JS中编写与XML类型的语言,但它与XML在本质上有所不同。它的目的不是要在浏览器或者引擎中发现,也不是把其加入ECMAScript标准。它的目的是通过各种编译器讲这些标记编译成标准的js语言。

JSX 语法

JSX本身就和XML语法相似,可以定义属性以及子元素。唯一特殊的是可以用大括号来加入Javascript表达式,例如

class HelloMessage extends React.Component {
    render() {
        return <div>Hello {this.props.name}</div>;
    }
}

ReactDOM.render(
        <HelloMessage name="Jerry"/>,
    document.getElementById('root')
);

JSX扩展属性

不要改变props

如果提前就知道了组件的属性的化,写起来很容易例如component组件有两个动态的属性foo和bar:
var component = <Component foo={x} bar={y} />;
而实际上,有些属性可能是后续添加的,我们没办法一开始就确定,我们可能会写出下面不好的代码:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
这样写是错误的,因为我们手动直接添加的属性React后续没办法检查到属性类型错误,也就是说,当我们手动添加的属性发生类型错误时,在控制台是看不到错误信息的。
在React的设定中,初始化完props后,props是不可变的。改变props会引起无法想象的后果。

扩展属性

为了解决这个问题,React引入了属性扩展
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
当需要拓展我们的属性的时候,定义个一个属性对象,并通过{...props}的方式引入,React会帮我们拷贝到组件的props属性中。重要的是—这个过程是由React操控的,不是手动添赋值的属性。
需要覆盖的时候可以这样写:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;

JSX陷阱

style属性

在React中写行内样式时,要这样写,不能采用引号的书写方式,因为JSX的属性是以对象的方式存在的。

ReactDOM.render(
    <div style={{color:'red'}}>
        xxxxx
    </div>,
    document.getElementById('root')   
);

HTML转义

var content='<strong>content</strong>';
ReactDOM.render(
    <div>{content}</div>,
    document.getElementById('root')   
);

结果页面直接输出内容了:
<strong>content</strong>

React默认会进行HTML的转义,避免XSS攻击,如果要不转义,可以这么写:

var content='<strong>content</strong>';
ReactDOM.render(
    <div dangerouslySetInnerHTML={{__html: content}}></div>,
    document.getElementById('root')   
);

页面输出:
content

自定义HTML属性

如果在编写React过程中使用了自定义属性,React不会渲染的; 如果需要使用自定义属性,要加 data- 的前缀。

布尔值、Null和Undefined被忽略

false、null、undefined和true都是有效的子代,但它们不会直接被渲染

React 必须声明

由于 JSX 编译后会调用 React.createElement 方法,所以在你的 JSX 代码中必须首先声明React变量。

JSX编译

<div className="red">Children Text</div>;
<MyCounter count={3 + 5} />;

// Here, we set the "scores" attribute below to a JavaScript object.
var gameScores = {
  player1: 2,
  player2: 5
};
<DashboardUnit data-index="2">
  <h1>Scores</h1>
  <Scoreboard className="results" scores={gameScores} />
</DashboardUnit>;

Babel在线编译:https://babeljs.io/repl/ 在线编译

HTML 标签对比 React 组件

React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。 要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。

var myDivElement = <div className="foo" />;
ReactDOM.render(
    myDivElement   ,
    document.getElementById('root')
);

要渲染 React 组件,只需创建一个大写字母开头的本地变量。

function UserGreeting(props) {
    return <h1>Welcome back!</h1>;
}
var myElement = <UserGreeting someProperty={true} />;
ReactDOM.render(
    myElement   ,
    document.getElementById('root')
);

React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。

注意: 由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

怎样指定 React 元素类型? JSX的标签名决定React元素的类型。

JSX转换过程

那么形如HTML标签实际上却是对象的React组件是如何构成的呢? 查看React源码如下:

var React = {
  Children: {
    map: mapChildren,
    forEach: forEachChildren,
    count: countChildren,
    toArray: toArray,
    only: onlyChild
  },

  Component: Component,
  PureComponent: PureComponent,
  unstable_AsyncComponent: AsyncComponent,

  Fragment: REACT_FRAGMENT_TYPE,

  createElement: createElementWithValidation,
  cloneElement: cloneElementWithValidation,
  createFactory: createFactoryWithValidation,
  isValidElement: isValidElement,

  version: ReactVersion,

  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
    ReactCurrentOwner: ReactCurrentOwner,
    // Used by renderers to avoid bundling object-assign twice in UMD bundles:
    assign: _assign
  }
};
module.exports = react;

import React from 'react' 时,引入的就是源码中提供的React对象。 在extends Component时,继承了Component类。这里需要说明两点:

  • 这里是列表文本源码中明明使用的module.exports而不是export default,为什么还能够成功引入呢?
    其实这是babel解析器的功劳。它令(ES6)import === (CommonJS)require。而在typescript中,需要严格的export default声明,故在typescript下就不能使用import React from 'react'了。
  • 我们可以写extends Component也可以写extends React.Component,这两者是否存在区别呢? 答案是否定的。因为Component是React.Component的引用。 也就是说Component === React.Component,在实际项目中写哪个都可以。

转载于:https://my.oschina.net/johnsken/blog/1649097

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值