React-JSX语法-2

XML基本语法:使用XML语法的好处是标签可以任意嵌套,可以像HTML一样清晰看到DOM树状结构及其属性

const List = () => (
    <div>
      <Title>This is title</Title>
      <ul>
        <li>list item</li>
      </ul>
    </div>
);

· 所有标签都必须闭合,否则无法编译通过;
· 定义标签时,只允许被一个标签包裹;只有一个标签会被转译成对应的React.createElement() 调用,否则无法被转译并调用React.createElement()

const component1 = <span>name</span><a>value</a>;   报错
const component2 = <div><span>name</span><span>value</span></div>; 不报错

元素类型:JSX语法分为两种不同的元素类型

·DOM元素:HTML标签首字母小写对应DOM元素
·组件元素:而组件元素首字母大写对应组件元素

JSX注释:在一个组件的子元素位置使用注释要用 {} 包起来

  const App = (
    <Nav>
      { 
      	// 节点注释  
      }
      <Person
        {/* 多行注释 */}
        className={style}
      />
    </Nav>
  );

元素属性:

JSX语法中,不论是DOM元素还是组件元素,它们都有属性。不同的是,DOM元素的属性是标准规范
属性,但是有两个例外————class和for需要转换:
	·class 属性改为 className
	·for 属性改为 htmlFor

Boolean属性:表单元素中,比如 disabled、require、checked 和 readOnly等,要传false时,必须使用属性表达式

  <checked checked={ true } /> || <checked checked={ false } />

展开属性:

  const data = { name: 'foo', value: 'bar' };
  const component = <Component name={ data.name } value={data.value} />
  可以写成:
  const component = <Component { ...data } />

自定义 HTML 属性:如果在 JSX 中往DOM元素传入自定义属性,React是不会渲染;如果要使用HTML自定义属性要使用 data- 前缀

  <div data-attr="xxx"></div> || <div data-attr={ xxx }></div>

javaScript属性表达式:属性值要使用表达式,用 {} 替换 “” 即可;

  const Person = <Person name={ window.isLoggedIn ? window.name : '' }/>;

子组件也可以作为表达式使用

 例1
  const content = <Container>{ window.isLoggerdIn ? <Nav/> : <Login/>}</Container>;
  
  例2
  let component = <Container/>;
  <Nav>{ component }</Nav>

HTML转义:React会将所有要显示到DOM的字符串转义,防止XSS攻击。以下5种办法都可以解决

·直接使用UTF-8字符;
·使用对应字符的Uncode编码查询编码;
·使用数组组装 <div>{ [ 'cc', <span>&nbso;</span>, '2018'] }</div>
·直接插入原始的HTML
·<div dangerouslySetInnerHtml={{__html: 'cc &nbsp; 2018'}}></div>

1、深入 JSX

JSX 其实就是 React.createElement( component, props, …children )

	<MyButton color="blue" shadowSize={2}>
		Click Me
	</MyButton>

	//编译为
	
	React.createElement(
		MyButton,
		{color: 'blue', shadowSize: 2},
		'Click Me'
	)

2、如果没有子级组件,可以使用自闭合标签

	<div className="sidebar" />
	
	//编译为:

	React.createElement(
		'div',
		{className: 'sidebar'},
		null
	);

3、指定 React 元素类型

·JSX 的标签名决定了 React 元素的类型大写开头的 JSX 标签表示一个 React 组件。这些标签将会被编译为同名变量并被引用,所以如果使用 表达式,则必须在作用域中先声明 Foo 变量。
·React 必须声明。由于 JSX 编译后会调用 React.createElement 方法,所以在 JSX 代码中必须首先声明 React 变量。

import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
	return <CustomButton color="red" />;
	// 返回 React.createElement(CustomButton, {color: 'red'}, null);
};

4、点表示法: JSX 中的 “点” 表示法来引用 React 组件。可以从一个模块中导出许多 React 组件

	import React from 'react';
	const MyComponents = {
		DatePicker: function DatePicker(props) {
			return <div>Imagine a {props.color} datepicker here.</div>;
		}
	};

	function BlueDatePicker() {
		return <MyComponents.DatePicker color="blue" />;
	}

5、首字母大写

当元素类型以小写字母开头时,它表示一个内置的组件,如 ‘div’ 或 span,并将字符串 ‘div’ 或 ‘span’ 传 递给 React.createElement。
以大写字母开头的类型,如 编译为 React.createElement(Foo),并它正对应于你在 JavaScript 文件中定义或导入的组件。

import React from 'react';
function HelloWorld(props){ // 组件首字母大写
	return <div>Hello {props.toWhat}</div>;  // HTML标签小写
};

6、在运行时选择类型

不能用 【 表达式 】 来作为 React 元素的标签。如果想通过表达式来确定 React 元素的类型,请先将其赋值给 【 大写 】 开头的变量。

import { PhotoStory, VideoStory } from './stories';
const components = {
	photo: PhotoStory,
	video: VideoStory
};

function Story(props) {
	// 错误!JSX 标签名不能为一个表达式。
	return	<components[props.storyType] story={props.story} />;

	// 正确!JSX 标签名可以为 "大写" 开头的变量。
	const SpecificStory = components[props.storyType];
	return <SpecificStory story={props.story} />;
};

7、属性: JSX 中有几种不同的方式来指定属性

1)使用 JavaScript 表达式可以传递任何 {} 包裹的 JavaScript 表达式作为一个属性值。

	<MyComponent foo={1 + 2 + 3 + 4} />
	//对于 MyComponent来说, props.foo 的值为 10,这是 1 + 2 + 3 + 4 表达式计算得出的。

2)if 语句和 for 循环在 JavaScript 中不是表达式,因此它们不能直接在 JSX 中使用,可以将它们放在周围的代码中。

function NumberDescriber(props) {
	let description = props.number % 2 == 0 ? <strong>even</strong> : <i>odd</i>;
	return <div>{props.number} is an {description} number</div>;
};

3)字符串常量属性值传递

	<MyComponent message="hello world" />
	// 等价于
	<MyComponent message={'hello world'} />

4)如果没有给属性传值,它默认为 true。

	<MyTextBox autocomplete />
	// 等价于
	<MyTextBox autocomplete={true} />

8、扩展属性

如果已经有了 props 对象,并且想在 JSX 中传递它,可以使用 … 作为扩展操作符来传递整个属性对象

	function App2() {
		// return <Greeting firstName="Ben" lastName="Hector" />;
		const props = {firstName: 'Ben', lastName: 'Hector'};
		return <Greeting {...props} />;
	};

11、子代
在包含开始和结束标签的 JSX 表达式中,标记之间的内容作为特殊的参数传递:props.children。有几种不同的方法来传递子代:

1)字符串常量: 在开始和结束标签之间放入一个字符串,则 props.children 就是那个字符串

<MyComponent>Hello world!</MyComponent>
这是有效的 JSX,并且 MyComponent 的 props.children 值将会直接是 "hello world!"

2)JSX 会移除空行和开始与结尾处的空格。标签邻近的新行也会被移除,字符串常量内部的换行会被压缩成一个空格

	<div>Hello World</div>

	<div>
		Hello World
	</div>

3)可以通过子代嵌入更多的 JSX 元素,对于嵌套显示组件非常有用:

	<MyContainer>
		<MyFirstComponent />
		<MySecondComponent />
	</MyContainer>

4)JSX可以混合不同类型的子元素,同时用字符串和 JSX 子元素,这是 JSX 类似 HTML 的另一种形式,这在 JSX 和 HTML 中都是有效的:

	<div>
	Here is a list:
	<ul>
		<li>Item 1</li>
		<li>Item 2</li>
	</ul>
	</div>

5)React 组件也可以通过数组的形式返回多个元素

	render() {
		// 不需要使用额外的元素包裹数组中的元素
		return [
			// 不要忘记 key :)
			<li key="A">First item</li>,
			<li key="B">Second item</li>,
			<li key="C">Third item</li>,
		];
	}

6)JavaScript 表达式,可以将任何 {} 包裹的 JavaScript 表达式作为子代传递,可以渲染任意长度的 JSX 表达式的列表

// 例1
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>

// 例2
function Item(props) { return <li> { props.message } </li>; };
function TodoList() {
	const todos = ['finish doc', 'submit pr', 'nag dan to review'];
	return (
		<ul>
			{todos.map((message) => <Item key={message} message={message} />)}
		</ul>
	);
};

7)JavaScript 表达式可以与其他类型的子代混合使用,通常用于字符串模板

function Hello(props) {
	// Hello {props.addressee} 混合使用
	return <div>Hello {props.addressee}!</div>;
};

8)函数,通常情况下插入 JSX 中的 JavaScript 表达式将被认作字符串、React 元素或这些内容的列表。然而,props.children 可以像其它属性一样传递任何数据,而不仅仅是 React 元素。

	//例如,如果使用自定义组件,则可以将调用 props.children 来获得传递的子代:

	function Repeat(props) {
		let items = [];
		for (let i = 0; i < props.numTimes; i++) {
			items.push(props.children(i));
		}
		return <div>{items}</div>;
	};

	function ListOfTenThings() {
		return (
			<Repeat numTimes={10}>
				{(index) => <div key={index}>This is item {index} in the list</div>}
			</Repeat>
		);
	};
	//传递给自定义组件的子代可以是任何元素,只要该组件在 React 渲染前将其转
	换成 React 能够理解的东西

9)布尔值、Null 和 Undefined 被忽略。false、null、undefined 和 true 都是有效的子代,但它们不会直接被渲染,根据条件来确定是否渲染React元素

	// 例1
	<div />
	<div></div>
	<div>{false}</div>
	<div>{null}</div>
	<div>{undefined}</div>
	<div>{true}</div>

	// 例2
	<div>
		{showHeader && <Header />}
		<Content />
	</div>

10)JavaScript 中的一些 “falsy” 值(比如数字0),它们依然会被渲染,要解决这个问题,确保 && 前面的表达式始终为布尔值:

	<div>
		{
			props.messages.length > 0 && <MessageList messages={ props.messages } />
		}
	</div>

11)如果让类似 false、true、null 或 undefined 出现在输出中,你必须先把它转换成字符串

<div>
	My JavaScript variable is { String( myVariable ) }
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值