JSX 其实是 React. createElement(component, props, …children) 函数的语法糖。故使用 jsx 前,需先引用 React 库。
1 2 3 4 5 6 7 8 9 10 11 12 import React from 'react';//先引用react库 <MyButton color="blue" shadowSize={2}> Click Me </MyButton> //上面jsx会编译成如下代码: React.createElement( MyButton, {color: 'blue', shadowSize: 2}, 'Click Me' )
1 JSX 组件标签
1 2 3 4 5 6 7 8 9 10 11 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" />; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { //错误,标签不能为表达式components[props.storyType] return <components[props.storyType] story={props.story} />; // 正确!JSX 类型可以是大写字母开头的变量。 const SpecificStory = components[props.storyType]; return <SpecificStory story={props.story} />; }
2 JSX 中的 Props JSX 中的 props 可以为 JS 表达式、字符串,props 属性的默认值为 ture,可以将对象使用展开运算符传递给Props。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //使用js表达式 <MyComponent foo={1 + 2 + 3 + 4} /> //下面两个字符串值等价 <MyComponent message="<3" /> <MyComponent message={'<3'} /> //下面两者等价,props 属性默认值为 true <MyTextBox autocomplete /> <MyTextBox autocomplete={true} /> //将对象使用展开运算符...传递给Props function App2() { const props = {firstName: 'Ben', lastName: 'Hector'}; return <Greeting {...props} />; }
3 JSX 中的子元素 JSX 组件的开始和结束标签之间的内容,会通过 Props.children 传递给组件。
3.1 字符串、表达式、函数 字符串为子元素时,JSX 会移除行首尾的空格及空行,字符串之间的新行会被压缩为一个空格,下面几种书写方式是等效的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <div>Hello World</div> <div> Hello World </div> <div> Hello World </div> <div> Hello World </div> //js表达式为子元素 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> ); } //函数为子元素 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> ); }
3.2 组件 1 2 3 4 <MyContainer> <MyFirstComponent /> <MySecondComponent /> </MyContainer>
3.3 布尔类型、Null 以及 Undefined 布尔类型、Null 以及 Undefined 将会忽略
1 2 3 4 5 6 7 8 9 10 11 12 //以下的 JSX 表达式渲染结果相同: <div /> <div></div> <div>{false}</div> <div>{null}</div> <div>{undefined}</div> <div>{true}</div>
值得注意的是有一些 “falsy” 值 ,如数字 0
,仍然会被 React 渲染。例如,以下代码并不会像你预期那样工作,因为当 props.messages
是空数组时,0
仍然会被渲染:
1 2 3 4 5 <div> {props.messages.length && <MessageList messages={props.messages} /> } </div>
要解决这个问题,确保 &&
之前的表达式总是布尔值:
1 2 3 4 5 <div> {props.messages.length > 0 && <MessageList messages={props.messages} /> } </div>
反之,如果你想渲染 false
、true
、null
、undefined
等值,你需要先将它们转换为字符串 :
1 2 3 <div> My JavaScript variable is {String(myVariable)}. </div>