导航
JSX 经过编译,变成 React.createElement 调用形式
App1JSX是createElement的语法糖.jsx
class App extends React.Component {
render() {
return (
// <div id="J_Box" className="box">
// <h1 className="title">
// This is a <span>TITLE</span>
// </h1>
// </div>
React.createElement(
'div',
{
className: 'box',
id: "J_Box"
},
React.createElement(
'h1',
{
className: 'title'
},
'This is a ',
React.createElement(
'span',
null,
'TITLE'
)
)
)
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App2React元素类型.jsx
class MyButton extends React.Component {
render() {
return (
<button>Click</button>
)
}
}
class App extends React.Component {
render() {
return (
/**
* React 元素类型
* MyButton -> React 元素
* 用到了一个 JSX 的组件,那么这个组件必须存在在当前模块的作用域中
* React 通过编译 JSX,将其转为 React.createElement 调用形式
* React 要使用 createElement ,就必须让 React 库存在在当前的模块作用域中
* 开发环境: import React from 'react';
* 生产环境: 在 index.html 的 script 的 src 中引入 React CDN
* 不需要 import React ,因为此时 React 是挂载到全局的
*/
<MyButton />
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
React 允许你把“组件”当作对象的属性来用
App3使用点语法.jsx
const colorSystem = {
'success': 'green',
'primary': 'blue',
'warning': 'orange',
'danger': 'red'
}
const MyUI = {
// 类组件
Button: class extends React.Component {
render() {
const { type, children } = this.props
return (
<button
style={{
color: '#fff',
backgroundColor: colorSystem[type]
}}
>{ children }</button>
)
}
},
// 函数组件
input: function(props) {
const { placeholder, changeValue } = props
return (
<input type="text"
placeholder={ placeholder }
onChange={ e => changeValue(e) } />
)
}
}
class App extends React.Component {
changeValue(e) {
console.log(e.target.value)
}
render() {
return (
<>
**<MyUI.Button** type="danger">Click</MyUI.Button>
**<MyUI.input** placeholder="请输入..." changeValue={ this.changeValue.bind(this) }></MyUI.input>
</>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
<div>、<h1>)
<MyButton />
App4运行时才选择React组件类型.jsx
class LoginBtnGroup extends React.Component {
render() {
return (
<div>
<button>登录</button>
<button>注册</button>
</div>
)
}
}
class WelcomeInfo extends React.Component {
render() {
return (
<div>
<h1>欢迎您, { this.props.username }</h1>
</div>
)
}
}
class Header extends React.Component {
static components = {
'login': LoginBtnGroup,
'welcome': WelcomeInfo
}
render() {
const HeaderUser = Header.components[this.props.type]
return (
// <components[this.props.type] { ...this.props } /> // 这样写会报错
<HeaderUser { ...this.props } />
)
}
}
class App extends React.Component {
render() {
return (
<Header
type="welcome"
username="Lance"
/>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
{} 里面可以传入任何 JavaScript 表达式(if, for, switch, function)App5JSX中的props.jsx 01
function MyTitle(props) {
const { title, author } = props
return (
<div>
<h1>{ title }</h1>
<p>{ author }</p>
</div>
)
}
class App extends React.Component {
render() {
return (
<MyTitle
title="This is a title"
author="Lance"
/>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App5JSX中的props.jsx 02
class App extends React.Component {
state = {
mainTitle: 'This is a MAIN TITLE',
subTitle: 'This is a SUB TITLE',
titleShow: 'main'
}
render() {
let title = ''
// if (this.state.titleShow === 'sub') {
// title = <h2>{ this.state.subTitle }</h2>
// } else if (this.state.titleShow === 'main') {
// title = <h1>{ this.state.mainTitle }</h1>
// } else {
// title = <h3>This is no TITLE</h3>
// }
switch (this.state.titleShow) {
case 'main':
title = <h1>{ this.state.mainTitle }</h1>
break;
case 'sub':
title = <h2>{ this.state.subTitle }</h2>
break
default:
title = <h3>This is no TITLE</h3>
break;
}
return (
<div>
{ title }
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
class App extends React.Component {
state = {
mainTitle: 'This is a MAIN TITLE',
subTitle: 'This is a SUB TITLE',
titleShow: 'main'
}
render() {
return (
<div>
{
this.state.titleShow === 'main'
? <h1>{ this.state.mainTitle }</h1>
: <h2>{ this.state.subTitle }</h2>
}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App5JSX中的props.jsx 03
function MyTitle(props) {
const { title, author } = props
return (
<div>
<h1>{ title }</h1>
<p>{ author }</p>
</div>
)
}
class App extends React.Component {
render() {
return (
<>
<MyTitle
title="这是标题"
author="Lance"
/>
<MyTitle
title={ '这是标题' }
author={ 'Lance' }
/>
<MyTitle
title="<这是标题>"
// JS表达式中,会准转义HTML实体(渲染的还是 < 而不是 <)
author={ '<Lance>' }
/>
<MyTitle
// 字符串字面量,不会转义HTML实体(会显示 < 而不是 <)
title="<这是标题>"
author={ '<Lance>' }
/>
</>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App5JSX中的props.jsx 04
function MyTitle(props) {
const { title, author, authorShow } = props
return (
<div>
<h1>{ title }</h1>
{
// 真假 boolean
authorShow === true
? <p>{ author }</p>
: ''
}
</div>
)
}
class App extends React.Component {
render() {
return (
<>
<MyTitle
title="这是标题"
author="Lance"
// 不推荐:字符串true,false代表字符串,不代表真假
// authorShow="true"
// 推荐:Boolean 的 true、false 才代表真假
authorShow={ true }
// 下面写法OK,但不推荐,有意思是ES6的省略属性值的歧义 {authorShow} => {authorShow: authorShow}
// authorShow
/>
</>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
{ ...this.props }const { a, ...others } = this.props,使用的时候 { ...other }this.props.children)App5JSX中的props.jsx 05
function MyTitle(props) {
const { children, title, author, authorShow } = props
return (
<div>
<h1>{ title }</h1>
{/* 获取 App 标签的 children */}
<h2>{ children }</h2>
{
// 真假 boolean
authorShow === true
? <p>{ author }</p>
: ''
}
</div>
)
}
class App extends React.Component {
// props全都要时,不推荐做法
// render() {
// const { title, author, authorShow } = this.props
// return (
// <>
// <MyTitle
// // props都要的话,推荐展开符,而不是下面这样
// title={ title }
// author={ author }
// authorShow={ authorShow }
// />
// </>
// )
// }
// props全都要时,推荐做法
// render() {
// return (
// <>
// <MyTitle
// // 推荐:
// { ...this.props }
// />
// </>
// )
// }
// props部分要时,可以排除不要的
// render() {
// const { a, ...others } = this.props
// return (
// <>
// <MyTitle
// // 推荐:
// { ...others }
// />
// </>
// )
// }
// children 传递
render() {
// others 包含 children ,因为 children 在 props 里(this.props.children)
const { a, ...others } = this.props
return (
<>
<MyTitle
// 推荐:
{ ...others }
/>
</>
)
}
}
ReactDOM.render(
// <App
// title="This is a title"
// author="Lance"
// authorShow={ true }
// a="123" />,
// children 获取:
<App
title="This is a title"
author="Lance"
authorShow={ true }
a="123">
This is a App
</App>,
document.getElementById('app')
)
)<br/>)App6JSX字符串字面量.jsx
class MyTitle extends React.Component {
render() {
return (
<h1>{ this.props.children }</h1>
)
}
}
class App extends React.Component {
render() {
return (
// 字符串字面量
// 1. 首尾空格自动去掉了
// <MyTitle> This is a TITLE </MyTitle>
// 2. 字符串之间多个空格,压缩为一个空格(想要多个空格,可以用字符实体 )
// <MyTitle> This is a TITLE </MyTitle>
// <MyTitle> This is a TITLE </MyTitle>
// 3. 字符串之间的换行,压缩成一个空格(想要换行,用 <br/>)
// <MyTitle> This
// is a
// TITLE </MyTitle>
// <MyTitle> This is a<br/> TITLE </MyTitle>
<MyTitle> { 'This is a <TITLE>' } </MyTitle>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App7JSX中的列表.jsx
class MyList extends React.Component {
render() {
return (
<div className={ this.props.listClassName }>
<h1>{ this.props.listTitle }</h1>
<ul className="my-list">
{ this.props.children }
</ul>
</div>
)
}
}
class ListItem extends React.Component {
render() {
return (
<li>{ this.props.children }</li>
)
}
}
class ListItems extends React.Component {
render() {
return [
<li key="1">This is my content1</li>,
<li key="2">This is my content2</li>,
<li key="3">This is my content3</li>
]
}
}
class ListItems2 extends React.Component {
render() {
return this.props.listData.map((item, index) => {
return <li key={ index }>{ item }</li>
})
}
}
class App extends React.Component {
state = {
listData: [
'This is my content1',
'This is my content2',
'This is my content3',
]
}
render() {
return (
<MyList
listClassName="my-list-container"
listTitle="This is my list"
>
{/* {
this.state.listData.map((item, index) => {
return <ListItem key={ index }>Hello, { item }</ListItem>
})
} */}
{/* 或者 */}
{/* <ListItems /> */}
{/* JSX 作为 JSX 子元素 */}
<ListItems2 listData={ this.state.listData } />
</MyList>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App8null_undefined_boolean.jsx
class App extends React.Component {
state = {
data: [],
show: true
}
render() {
return (
<div>
{/*
null, undefined, bool 都是可以作为 JSX 的子元素
这些子元素是会被忽略不会渲染的,因为他们可以用来解决条件渲染的问题
*/}
<div>{ true }</div>
<div>{ false }</div>
<div>{ undefined }</div>
<div>{ null }</div>
{/* 下面 String(null) 显示 null 字符串 */}
<div>{ String(null) }</div>
<div>{
this.state.show ? 'OK' : '不OK'
}</div>
<div>{
this.state.show && 'OK'
}</div>
{/* JSX中,0是会渲染的 */}
{/* 这样可以,显示 无数据 */}
<div>{ this.state.data.length ? '有数据' : '无数据' }</div>
{/* 但这样会显示0 */}
<div>{ this.state.data.length && '有数据' }</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
props.children 跟 props 本身有一致性的特性
props.children 可以传递任何类型的子元素App9JSX函数子元素的应用于思考.jsx
// JSX函数子元素
/**
* JSX的 props.children 跟 props 本身有一致性的特性
* props.children 可以传递任何类型的子元素
*/
class Repeat extends React.Component {
render() {
const jsxArr = []
for (let i = 0; i < this.props.num; i++) {
jsxArr.push(this.props.children(i))
}
return jsxArr
/**
* [
* <p>This is item 1</p>,
* <p>This is item 2</p>,
* <p>This is item 3</p>,
* ...
* ]
*/
}
}
class App extends React.Component {
render() {
return (
<div>
<Repeat num={ 10 }>
{
(index) => <p key={ index }>This is item {index + 1}.</p>
}
</Repeat>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
App9JSX函数子元素的应用于思考2.jsx
// 接口启动地址:<http://localhost:8080/getStudents>
// 接口地址:23高阶组件1/server
import Http from './Http'
class App extends React.Component {
render() {
return (
<table border="1">
<thead>
<tr>
<td>ID</td>
<th>姓名</th>
<th>年级</th>
</tr>
</thead>
<tbody>
{/* 这里用到的 Http.Get 点语法的形式,就类似 React.Provider 的点语法 */}
<Http.Get
url="<http://localhost:8080/getStudents>"
loading={
<tr>
<td colSpan="3">正在加载中...</td>
</tr>
}
>
{
data => {
console.log(data)
return data.map(item => {
return <tr key={ item.id }>
<td>{ item.id }</td>
<td>{ item.name }</td>
<td>{ item.grade }</td>
</tr>
})
}
}
</Http.Get>
</tbody>
</table>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
Http/GET.jsx
class Get extends React.Component {
state = {
data: [],
component: this.props.loading || 'Loading'
}
async componentDidMount() {
const result = await axios(this.props.url)
this.setState({
data: result.data
}, () => {
this.setState({
component: this.props.children(this.state.data)
})
})
}
render() {
return this.state.component
}
}
export default Get
Http/index.jsx
import Get from './Get'
export default {
Get
}