React高级指南(一)【JSX In Depth】
JSX In Depth从根本上讲,JSX只是 <MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
会被编译为: React.createElement(
MyButton,{color: 'blue',shadowSize: 2},'Click Me'
)
如果不存在子节点,你可以使用自闭合格式的标签。例如: <div className="sidebar" />
会被编译为: React.createElement(
'div',{className: 'sidebar'},null
)
如果你想要了解JSX是如何编译为JavaScript,可以尝试在线Babel编译器. 指定React元素类型JSX标签的开始部分决定了React元素的类型。 首字母大写的标签指示JSX标签是一个React组件。这些标签会被编译成命名变量的直接引用。所以如果你使用JSX的 React必须在作用域中存在因为JSX被编译为调用 例如,在下面的代码中,虽然 import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
// return React.createElement(CustomButton,{color: 'red'},null);
return <CustomButton color="red" />;
}
如果你没有选择打包JavaScript,而是通过在script标签中添加了React,那么全局中已经存在 对JSX类型使用点表示法在JSX中,你可以通过点表示法引用React组件。如果仅有一个单一模块(module),但却对外提供多个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" />;
}
自定义组件必须以大写字母开头对于以小写字母开头的元素类型,其表示类似于 我们建议给组件以大写字母开头的方式命名。如果你已经有以小写字母开头的组件,需要在JSX中使用前将其赋值给以大写字母开头的变量。例如下面代码无法按照预期运行: import React from 'react';
// Wrong! This is a component and should have been capitalized:
function hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Wrong! React thinks <hello /> is an HTML tag because it's not capitalized:
return <hello toWhat="World" />;
}
为了修复这个问题,我们将 import React from 'react';
// Correct! This is a component and should be capitalized:
function Hello(props) {
// Correct! This use of <div> is legitimate because div is a valid HTML tag:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// Correct! React knows <Hello /> is a component because it's capitalized.
return <Hello toWhat="World" />;
}
运行时决定React类型不能使用普通的表达式作为React元素类型。如果你想使用通用表达式来表示元素类型,首先你需要将其赋值给大写的变量。这通常会出现在出现在根据不同的props渲染不同的组件: import React from 'react';
import { PhotoStory,VideoStory } from './stories';
const components = {
photo: PhotoStory,video: VideoStory
};
function Story(props) {
// Wrong! JSX type can't be an expression.
return <components[props.storyType] story={props.story} />;
}
为了解决这个问题,首先需要将其赋值给一个以大写字母开头的变量。 import React from 'react';
import { PhotoStory,video: VideoStory
};
function Story(props) {
// Correct! JSX type can be a capitalized variable.
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
JSX中的props在JSX中有下面几种不同的方式赋值props。 JavaScript 表达式你可以给props传递一个用 <MyComponent foo={1 + 2 + 3 + 4} />
对 对于JavaScript, function NumberDescriber(props) {
let description;
if (props.number % 2 == 0) {
description = <strong>even</strong>;
} else { description = <i>odd</i>; }
return <div>{props.number} is an {description} number</div>;
}
字符串你可以给prop传入字符串,下面两种JSX表达式是等价的: <MyComponent message="hello world" />
<MyComponent message={'hello world'} />
当给props传递字符串时,其值是未转义的HTML(HTML-unescaped)。下面两种JSX表达式是等价的: <MyComponent message="<3" />
<MyComponent message={'<3'} />
这种行为通常讲并不重要,这里所提到的只是为了完整性。 Props Default to “True”如果prop没有传入值,默认为 <MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
通常情况下,我们不建议使用这种类型,因为这会与ES6中的对象shorthand混淆。ES6 shorthand中 属性展开如果存在一个object类型的 function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben',lastName: 'Hector'};
return <Greeting {...props} />;
}
当你构建一个container时,属性展开非常有用。然而,这可能会使得你的代码非常混乱,因为这使得非常多不相关的props传递给组件,但组件并不需要这些props。因此我们建议谨慎使用该语法。 JSX中的Children在包括开标签和闭标签在内的JSX表示式中,标签中的内容会被传递一个特殊的props: 字符串您可以在开标签和闭合标签中写入字符串,这对于内置HTML元素非常有用,例如: <MyComponent>Hello world!</MyComponent>
这是有效的JSX, <div>This is valid HTML & JSX at the same time.</div>
JSX会删除每行开头和结尾的空格,并且也会删除空行。邻接标签的空行也会被移除,字符串之间的空格会被压缩成一个空格,因此下面的渲染效果都是相同的: <div>Hello World</div> <div> Hello World </div>
<div> Hello World </div> <div> Hello World </div>
JSX Children你可以传递多个JSX元素作为子元素,这对显示嵌套组件非常有用: <MyContainer>
<MyFirstComponent /> <MySecondComponent /> </MyContainer>
你可以混合不同类型的子元素,因此你可以混用字符串和JSX子元素。这是JSX与HTML另一点相似的地方,因此下面是HTML和JSX均是有效的: <div>
Here is a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
React组件不能返回多个React元素,但是单个JSX表达式可以有多个子元素,因此如果你想要渲染多个元素,你可以像上面一样,将其包裹在 JavaScript 表达式通过使用 <MyComponent>foo</MyComponent> <MyComponent>{'foo'}</MyComponent>
这对于渲染长度不定的JSX表达式列表非常有用,例如,下面会渲染HTML list: 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>
);
}
JavaScript表达式可以和其他类型的子元素混用,这对于字符串模板非常有用: function Hello(props) {
return <div>Hello {props.addressee}!</div>;
}
Function类型的子元素通常情况下,嵌入JSX中的JavaScript表达式会被认为是字符串、React元素或者是这些内容的列表。然而, // Calls the children callback numTimes to produce a repeated component
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能够处理的东西即可。这种用法并不常见,但是如果你需要扩展JSX的话,则会非常有用。 Booleans,Null和Undefined都会被忽略
<div />
<div></div> <div>{false}</div> <div>{null}</div> <div>{undefined}</div> <div>{true}</div>
在有条件性渲染React元素时非常有用。如果 <div>
{showHeader && <Header />}
<Content />
</div>
需要注意的是,React仍然提供了“falsy”值,例如数值 <div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
为了解决这个问题,你只要确保&&`前的表达式是boolean类型: <div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
反过来,如果在输出中想要渲染 <div>
My JavaScript variable is {String(myVariable)}.
</div>
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |