React中JSX的理解 (2)

通常可以通过使用引号来将属性值指定为字符串字面量,也可以使用大括号来在属性值中插入一个JavaScript表达式,在属性中嵌入JavaScript表达式时,不要在大括号外面加上引号。因为JSX语法上更接近JavaScript而不是HTML,所以React DOM使用camelCase小驼峰命名来定义属性的名称,而不使用HTML属性名称的命名约定。例如JSX里的class变成了className,而tabindex则变为tabIndex。

const element1 = <div tabIndex="0"></div>; const element2 = <img src=http://www.likecs.com/{user.avatarUrl}></img>;

JSX中也可以使用</>来闭合标签,另外JSX同样也可以直接定义很多子元素。

const element1 = <img src=http://www.likecs.com/{user.avatarUrl} />; const element2 = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> );

你可以安全地在JSX当中插入用户输入内容,React DOM在渲染所有输入内容之前,默认会进行转义,这样可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容,所有的内容在渲染之前都被转换成了字符串,可以有效地防止 XSS跨站脚本攻击。

const title = response.potentiallyMaliciousInput; // 直接使用是安全的: const element = <h1>{title}</h1>;

实际上Babel会把JSX转译成一个名为React.createElement()函数调用,通过React.createElement()定义的元素与使用JSX生成的元素相同,同样这就使得JSX天生就是需要编译的。

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

React.createElement()会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象。这些对象被称为React 元素,它们描述了你希望在屏幕上看到的内容,React通过读取这些对象,然后使用它们来构建DOM以及保持随时更新。

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

实际上,这就是虚拟DOM的一个节点,Virtual DOM是一种编程概念,在这个概念里,UI以一种理想化的,或者说虚拟的表现形式被保存于内存中,并通过如ReactDOM等类库使之与真实的DOM同步,这一过程叫做协调。这种方式赋予了React声明式的API,您告诉React希望让UI是什么状态,React就确保DOM匹配该状态,这样可以从属性操作、事件处理和手动DOM更新这些在构建应用程序时必要的操作中解放出来。
与其将Virtual DOM视为一种技术,不如说它是一种模式,人们提到它时经常是要表达不同的东西。在React的世界里,术语Virtual DOM通常与React元素关联在一起,因为它们都是代表了用户界面的对象,而React也使用一个名为fibers的内部对象来存放组件树的附加信息,上述二者也被认为是React中Virtual DOM 实现的一部分,Virtual DOM也为使用diff算法奠定了基础。

<div> <p>1</p> <div>11</div> </div> // 使用Js对象去描述上述节点以及文档 { type: "tag", tagName: "div", attr: { className: "root" name: "root" }, parent: null, children: [{ type: "tag", tagName: "p", attr: {}, parent: {} /* 父节点的引用 */, children: [{ type: "text", tagName: "text", parent: {} /* 父节点的引用 */, content: "1" }] },{ type: "tag", tagName: "div", attr: {}, parent: {} /* 父节点的引用 */, children: [{ type: "text", tagName: "text", parent: {} /* 父节点的引用 */, content: "11" }] }] } 示例 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>JSX示例</title> </head> <body> <div></div> </body> <script src="http://unpkg.com/react@17/umd/react.development.js"></script> <script src="http://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="http://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } componentDidMount() { this.timer = setInterval(() => this.tick(), 1000); } componentWillUnmount() { clearInterval(this.timer); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>{this.props.tips}</h1> <h2>Now: {this.state.date.toLocaleTimeString()}</h2> </div> ); } } class App extends React.Component{ constructor(props){ super(props); this.state = { showClock: true, tips: "Hello World!" } } updateTips() { this.setState((state, props) => ({ tips: "React update" })); } changeDisplayClock() { this.setState((state, props) => ({ showClock: !this.state.showClock })); } render() { return ( <div> {this.state.showClock && <Clock tips={this.state.tips} />} <button onClick={() => this.updateTips()}>更新tips</button> <button onClick={() => this.changeDisplayClock()}>改变显隐</button> </div> ); } } var vm = ReactDOM.render( <App />, document.getElementById("root") ); </script> </html> 每日一题 https://github.com/WindrunnerMax/EveryDay 参考 https://www.zhihu.com/question/265784392 https://juejin.cn/post/6844904127013584904 https://zh-hans.reactjs.org/docs/introducing-jsx.html

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsswxw.html