const isLoading = trueconst loadData = ()=>{ return isLoading ? ( <div> 数据加载中,请稍后...</diV> ) : (<div> 数据加载完成,此处显式加载后的数据</diV>)}const dv = ( <div> { loadData() } </div>)
const isLoading = true/ isLoading 为TRUE 则显示 数据加载中,请稍后... /const loadData = ()=>{ return isLoading && ( <div> 数据加载中,请稍后...</diV> )}const dv = ( <div> { loadData() } </div>)
4.4 JSX的 列表渲染如果要渲染一组数据,应该使用数组的 map() 方法注意:渲染列表时应该添加 key 属性, key 属性的值要保证唯一原则: map() 遍历谁,就给谁添加 key 属性注意: 尽量避免使用索引号作为 key
const songs = [ {id:1,name:"黄种人"}, {id:2,name:"中国人"}, {id:3,name:"我的中国心"},]const list = ( <ul> {songs.map(item => (<li key={item.id}> {item.name} </li>) )} </ul>)
4.5 JSX的 样式处理行内样式--style(耦合太紧密,不推荐)
<h1 style={{color:'red',background:'skyblue'}}> JSX 的样式处理</h1>
类名--className(推荐)
//先引入 css 文件import './style.css'const list = ( <h1 className="title"> JSX 的样式处理 </h1>)
JSX1.JSX是React 的核心内容。2.JSX 表示在JS代码中写HTML结构,是React声明式的体现。3.使用 JSX 配合嵌入的 JS 表达式、条件渲染、列表渲染,可以描述任意 U结构。4. 推荐使用 className 的方式给JSX加样式,5.React 完全利用 JS 语言自身的能力来编写UI,而不是造轮子增强 HTML 功能。

function Hello(){ return ( <div> 这是我的第一个函数组件!
5.2.2 渲染函数组件:渲染函数组件: 用函数名作为组件标签名,组件标签可以是单标签也可以是双标签
</div> )}
import React from 'react'import ReactDOM from 'react-dom'//创建组件function Hello(){ return ( <div> 这是我的第一个函数组件!
函数也可以是箭头函数
</div> )}//渲染组件 用函数名作为组件标签名ReactDOM.render(<Hello />,document.getElementById('root'))
import React from 'react'import ReactDOM from 'react-dom'//创建组件const Hello = () => (<div> 这是我的第一个函数组件!
5.2.3 使用 类 创建组件类组件: 使用 ES6 的 class 创建的组件约定:类名称也必须是大写字母开头约定:类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法和属性约定:类名称必须提供 render() 方法约定:render() 方法必须由返回值,表示该组件的结构
</div>)//渲染组件 用函数名作为组件标签名ReactDOM.render(<Hello />,document.getElementById('root'))
import React from 'react'import ReactDOM from 'react-dom'//创建类组件class Hello extends React.Component { render(){ return <div>Class Component!</div> }}//渲染组件 ReactDOM.render(<Hello />,document.getElementById('root'))
5.2.4 抽离为独立 js文件思考:项目中的组件多了之后,该如何组织这些组件呢?选择一: 将所有的组件放在同一个 js 文件中选择二: 将每个组件放在单独的 js 文件中组件作为一个独立的个体,一般都会是放到一个单独的 js 文件中1、创建 Hello.js2、在 Hello.js 中导入 React3、创建组件( 函数 或 类)4、在 Hello.js 中导出该组件5、在 index.js 中导入 Hello 组件6、渲染组件
//Hello.jsimport React from 'react'//创建类组件class Hello extends React.Component{ render(){ return (<div>Hello Class Component!</div>) }}//导出 Hello 组件export default Hello
import React from 'react'import ReactDOM from 'react-dom'//导入抽离的组件import Hello from './Hello'//渲染导入的 Hello 组件ReactDOM.render(<Hello />,document.getElementById('root'))
5.3 React事件处理5.3.1 事件绑定react 事件绑定语法 与 DOM 事件语法相似语法: on+事件名称={事件处理程序},比如:onClick={ ()=>{ } }语法:React 事件采用驼峰命名法,比如:onMounseEnter、onFocus在函数组件中绑定事件
class App extends React.Component{ //事件处理程序 handleClick (){ console.log( "单击事件触发了!
") } //渲染页面 render(){ return ( <button onClick={this.handleClick}>点击</button> ) }}
function App(){ //事件处理程序 function handleClick(){ console.log( "单击事件触发了!
5.3.2 事件对象可以通过 事件处理程序的参数 获取到事件对象React 中的事件对象叫做: 合成事件(对象)合成事件: 兼容所有浏览器,无需担心跨浏览器兼容性问题
!
") } //渲染页面 return ( <button onClick={this.handleClick}>点击</button> )}
class App extends React.Component{ //事件处理程序 handleClick (e){ e.preventDefault () console.log( "单击事件触发了!
5.4 有状态组件和无状态组件函数组件又叫做 无状态组件, 类组件又叫做 有状态组件状态 (state) 即数据函数组件没有自己的状态,只负责数据展示(静)类组件有自己的状态,负责更新UI,让页面“动”起来
") } //渲染页面 render(){ return ( <a onClick={this.handleClick}>点我,不会跳转页面</a> ) }}
比如计数器案例中,单击按钮让数值加 1。
0 和 1 就是不同时刻的状态,而由 0 变为 1 就表示状态发生了变化。
状态变化后,UI 也要相应的更新。
React 中想要实现该功能,就要使用有状态组件来完成。
5.5 组件中的 state和 setState()5.5.1 state的基本使用状态(state) 即数据,是组件内部的私有数据,只能在组件内部使用state 的值是对象,表示一个组件中可以有多个数据获取状态: this.state
class Hello extends React.Component{ constructor(){ super() //初始化state this.state = { count:0 } } //渲染页面 render(){ return ( <div>有状态组件 {this.state.count}</div> ) }}
简化写法(推荐使用):
class Hello extends React.Component{ //初始化state state = { count:0 } //渲染页面 render(){ return ( <div>有状态组件 计数器:{this.state.count}</div> ) }}
5.5.2 setState()修改状态状态是可变的语法: this.setState({要修改的数据})注意: 不要直接修改state 中的值,这是错误的!
setState()的作用: 1、修改state,2、 更新UI思想: 数据驱动视图
class App extends React.Component{ //初始化state state = { count: 0, text: 'aaa' } //渲染页面 render(){ return ( <div> <div>有状态组件 计数器:{this.state.count}</div> <button onClick={()=>{ this.setState({ count:this.state.count +1 }) }}> 点击 + 1 </button> </div> ) }}
5.5.3 从 JSX中抽离事件处理程序JSX 中掺杂过多 JS 逻辑代码,会显得非常混乱推荐: 将逻辑抽离到单独的方法中,保证 JSX 结构清晰报错: TypeError:Cannot read property 'setState' of undefineds原因:事件处理程序中 this 的值为 undefined希望: this 指向组件实例( render 方法中的 this 即为组件实例)
class App extends React.Component{ //初始化state state = { count:0, text:'aaa' } //事件处理程序--事件处理程序中 `this` 的值为 `undefined` onIncrement(){ this.setState({ count: this.state.count +1 }) } //渲染页面 render(){ return ( <div> <div>有状态组件 计数器:{this.state.count}</div> <button onClick={this.onIncrement()}> 点击 + 1 </button> </div> ) }}
5.7 事件绑定 this指向5.7.1 箭头函数利用箭头函数自身不绑定 this 的特点render() 方法中的 this 为组件实例,可以获取到 setState()
class App extends React.Component{ //初始化state state = { count:0, text:'aaa' } //事件处理程序 onIncrement(){ this.setState({ count:this.state.count +1 }) } //渲染页面 render(){ return ( <div> <div>有状态组件 计数器:{this.state.count}</div> <button onClick={() => this.onIncrement() }> 点击 + 1 </button> </div> ) }}
5.7.2 Function.prototype.bind()利用 ES5 中的 bind 方法,将事件处理程序中的 this 与组件实例绑定到一起
class App extends React.Component{ constructor(){ super() //初始化state this.state = { count:0, text:'aaa' } //利用 `ES5` 中的 `bind` 方法,将事件处理程序中的 `this` 与组件实例绑定到一起 this.onIncrement = this.onIncrement.bind(this) } //事件处理程序 onIncrement(){ this.setState({ count:this.state.count +1 }) } //渲染页面 render(){ return ( <div> <div>有状态组件 计数器:{this.state.count}</div> <button onClick={ this.onIncrement }> 点击 + 1 </button> </div> ) }}
5.7.3 class的实例方法(推荐使用此方法)利用箭头函数形式的 class 实例方法注意: 该语法是实验性语法,但是,由于 babel 的存在可以直接使用
class App extends React.Component{ //初始化state state = { count:0, text:'aaa' } //事件处理程序 onIncrement = () => { //利用箭头函数形式的 `class` 实例方法 this.setState({ count: this.state.count +1 }) } //渲染页面 render(){ return ( <div> <div>有状态组件 计数器:{this.state.count}</div> <button onClick={ this.onIncrement }> 点击 + 1 </button> </div> ) }}
5.8 表单处理5.8.1 受控组件HTML 中的表单元素是可输入的,也就是有自己的可变状态而,React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改React 将 state 与表单元素值 value 绑定到一起,由 state 的值来控制表单元素的值受控组件: 其值收到 React 控制的表单元素
<input type="text" value={this.state.text} />
5.8.2 步骤:1、在 state 中添加一个状态,作为表单的 value 的值( 控制表单元素值的 来源 )2、给表单元素绑定 change 事件,将表单元素的值 设置为 state 的值( 控制表单元素值的 变化 )
class App extends React.Component{ //初始化state state = { txt:'aaa' } //事件处理程序 handleChange = e =>{ this.setState({ txt: e.target.value }) } //渲染页面 render(){ return ( <div> <input type="text" value={this.state.txt} onChange={this.handleChange}/> </div> ) }}
5.8.3 示例文本框、富文本框、下拉框 操作 value 的值复选框: 操作 checked 的值
class App extends React.Component{ //初始化state state = { txt:'aaa', content:'', city:'', isChecked:false } //事件处理程序 handleChange = e =>{ this.setState({ txt:e.target.value }) } handleContent = e =>{ this.setState({ content:e.target.value }) } handleCity = e =>{ this.setState({ city:e.target.value }) } handleChecked = e =>{ this.setState({ isChecked:e.target.checked }) } //渲染页面 render(){ return ( <div> {/ 文本框 /} <input type="text" value={this.state.txt} onChange={this.handleChange}/> {/ 富文本框 /} <textarea value={this.state.content} onChange={this.handleContent}></textarea> {/ 下拉框 /} <select value={this.state.city} onChange={this.handleCity}> <option value="sh">上海</option> <option value="bj">北京</option> <option value="gz">广州</option> </select> {/ 复选框 /} <input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked}/> </div> ) }}
5.8.4 !!!多个表单元素优化:问题:每个表单元素都有一个单独的事件处理程序处理太繁琐优化: 使用一个事件处理程序同时处理多个表单元素优化步骤:给表单元素添加 name 属性,名称与 state 相同根据表单元素类型获取对应值在 change 事件处理程序中通过 [name] 来修改对应的 state
<input type="text" name="txt" value={this.state.txt} onChange={this.handleForm} />
//根据表单元素类型取值const value = target.type === 'checkbox' ? target.checked : target.value//根据name 设置对应的 statethis.setState({ [name]:value})
class App extends React.Component{ //初始化state state = { txt:'aaa', content:'', city:'', isChecked:false } //事件处理程序 handleForm = e =>{ //获取当前DoM 对象 const target = e.target //根据表单元素类型取值 const value = target.type === 'checkbox' ? target.checked : target.value //获取name const name = target.name this.setState({ [name]:value }) } //渲染页面 render(){ return ( <div> {/ 文本框 /} <input type="text" name="txt" value={this.state.txt} onChange={this.handleForm}/> {/ 富文本框 /} <textarea value={this.state.content} name="content" onChange={this.handleForm}> </textarea> {/ 下拉框 /} <select name="city" value={this.state.city} onChange={this.handleForm}> <option value="sh">上海</option> <option value="bj">北京</option> <option value="gz">广州</option> </select> {/ 复选框 /} <input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm}/> </div> ) }}
5.8.5 非受控组件 (DOM方式)说明: 借助 ref ,使用原生 DOM 方式来获取表单元素值ref 的作用: 获取 DOM 或组件使用步骤:1、调用 React.createRef() 方法创建一个 ref 对象
constructor(){ super() this.txtRef = React.createRef()}
2将创建好的 ref 对象添加到文本框中
<input type="text" ref={ this.txtRef } />
3、通过 ref 对象获取到文本框的值
console.log( this.txtRef.current.value)
class App extends React.Component{ constructor(){ super() //创建 ref this.txtRef = React.createRef() } //初始化state state = { txt:'aaa', content:'', city:'', isChecked:false } //事件处理程序 getTxt = e =>{ // 通过 `ref` 对象获取到文本框的值 console.log( this.txtRef.current.value) //获取当前DoM 对象 const target = e.target //根据表单元素类型取值 const value = target.type === 'checkbox' ? target.checked : target.value //获取name const name = target.name this.setState({ [name]:value }) } //渲染页面 render(){ return ( <div> {/ 文本框 /} <input type="text" name="txt" ref={this.txtRef} value={this.state.txt} onChange={this.handleForm}/> <button onClick={this.getTxt}>点击获取文本框的值</button> </div> ) }}