8.6 KiB
8.6 KiB
组件介绍
组件表示页面中的部分功能 组合多个组件实现完整的页面功能 可复用,独立(相互之间互不影响),可组合
组件的创建方式
使用函数创建组件
函数名称必须以大写字母开头 必须有返回值,返回组件结构 如果返回null表示不渲染任何内容
渲染组件:使用函数名作为组件标签名
// function Hello(){
// return (<div>展示的返回函数组件</div>)
// }
const Hello =()=><div>展示的返回函数组件</div>
ReactDOM.render(<Hello />,document.getElementById('root'))
使用类创建组件
类名称必须以大写字母开头 类组件必须继承React.Component父类 必须提供render方法 render方法必须有返回值.
class HelloClass extends React.Component{
render(){
return (<div>leizujian</div>)
}
}
ReactDOM.render(<HelloClass />,document.getElementById('root'))
抽离到独立的js文件
- 创建HelloRender.js文件
- 在HelloRender.js文件中导入React
- 创建组件
- 在HelloRender.js中导出该组件
- 在index.js中导入HelloRender组件
- 渲染组件
import HelloRender from './learn/HelloRender'
ReactDOM.render(<HelloRender />,document.getElementById('root'))
import React from "react"
class HelloRender extends React.Component{
render(){
return (
<div>抽离到js文件中的组件</div>
)
}
}
export default HelloRender
事件处理
驼峰命名 on+事件名称={事件处理程序}
类
class AppOnClick extends React.Component{
handleClick(){
console.log('单机')
}
render(){
return (
<button onClick={this.handleClick}>点击</button>
)
}
}
ReactDOM.render(<AppOnClick />,document.getElementById('root'))
函数
function AppOnClickFun(){
function handleClick(){
console.log('单机function')
}
return (
<button onClick={handleClick}>点击</button>
)
}
ReactDOM.render(<AppOnClickFun />,document.getElementById('root'))
事件对象
class AppOnClickUrl extends React.Component{
handleClick(e){
// 阻止浏览器默认跳转行为
e.preventDefault()
console.log('单机,阻止浏览器默认跳转行为')
}
render(){
return (
<a href="http://www.baidu.com" onClick={this.handleClick}>点击</a>
)
}
}
ReactDOM.render(<AppOnClickUrl />,document.getElementById('root'))
有状态组件和无状态组件
状态(state)即数据 函数组件又叫无状态组件,只负责数据展示(静) 类组件又叫有状态组件,负责更新UI,让页面动起来
组件中的state和setState
class AppState extends React.Component{
constructor(){
super()
this.state= {
count:0
}
}
// state= {
// count:0
// }
render(){
return (
<div>有状态组件,{this.state.count}</div>
)
}
}
ReactDOM.render(<AppState />,document.getElementById('root'))
修改状态
class AppState extends React.Component{
constructor(){
super()
this.state= {
count:0,
test:'a'
}
}
// state= {
// count:0
// }
render(){
return (
<div>有状态组件,{this.state.count},{this.state.test}
<button onClick={()=>{
this.setState({
count:this.state.count+1
})
}}>+1</button>
</div>
)
}
}
ReactDOM.render(<AppState />,document.getElementById('root'))
事件处理程序中this的值为undefined,希望this指向组件实例 事件绑定this指向
- 箭头函数,利用箭头函数自身不绑定this的特点.
class AppStateJTThis extends React.Component{
constructor(){
super()
this.state= {
count:0
}
}
onIncrement(){
console.info('事件处理this'+this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>有状态组件,{this.state.count}
<button onClick={()=>this.onIncrement()}>+1</button>
</div>
)
}
}
ReactDOM.render(<AppStateJTThis />,document.getElementById('root'))
- Function.prototype.bind()利用ESS中bind方法,将时间处理程序中的this与组件实例绑定到一起
class AppStateJTThis extends React.Component{
constructor(){
super()
this.onIncrement= this.onIncrement.bind(this)
this.state= {
count:0
}
}
onIncrement(){
console.info('事件处理this'+this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>有状态组件,{this.state.count}
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
ReactDOM.render(<AppStateJTThis />,document.getElementById('root'))
- class实例方法
class AppStateJTThis extends React.Component{
constructor(){
super()
this.state= {
count:0
}
}
onIncrement=()=>{
console.info('事件处理this'+this)
this.setState({
count:this.state.count+1
})
}
render(){
return (
<div>有状态组件,{this.state.count}
<button onClick={this.onIncrement}>+1</button>
</div>
)
}
}
ReactDOM.render(<AppStateJTThis />,document.getElementById('root'))
方法是一个特殊的属性. 类中的方法默认开启了局部严格模式,所以changeWeather中的this为undefined, use strict 使用严格模式
实例调用,直接调用(严格模式下,this为undefined)
组件内的标签可以定义ref属性来标识自己
箭头函数中的this找外层的this.
事件处理
- 通过onXxx属性指定事件处理函数,必须驼峰
- React使用的是自定义合成事件,而不是使用原生DOM事件,为了更好兼容性
- React中的事件是通过事件委托方式处理的(委托给组件最外层的元素),为了更高效
- 可以通过event.target得到发生事件的DOM元素对象,避免过度使用ref
表单处理
受控组件,其值受到React控制的表单元素
- html中表单元素是可输入的,也就是有自己的可变状态
- react中可变状态通常通过state处理,并且只能通过setState()来处理
- react将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
- 类似vue中双向绑定
使用步骤
- 在state中添加一个状态,作为表单元素的value值(控制表单元素的来源)
- 给表单元素绑定change事件,将表单元素的值设置为state值(控制表单元素值的变化)
使用一个事件处理程序同时处理多个表单元素
- 给表单添加一个name属性,名称与state相同
- 根据表单元素类型获取对应值
- 在change事件处理程序中通过name来修改对应的state
class AppInput extends React.Component{
constructor(){
super()
this.state= {
txt:'请输入值',
context:'',
city:'bj',
isChecked:false
}
}
handleClick=e=>{
console.info('事件处理this'+this)
const target = e.target;
const value = target.type === 'checkbox'?target.checked:target.value
const name = target.name
this.setState({
[name]: value
})
console.info('name:'+name+',value:'+value)
}
render(){
return (
<div><input type='text' name='txt' value = {this.state.txt} onChange={this.handleClick}/>
<br/>
<textarea value={this.state.context} name= 'context' onChange={this.handleClick}/>
<br/>
<select value={this.state.city} onChange={this.handleClick} name = 'city'>
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select>
<input type='checkbox' name='isChecked' checked = {this.state.isChecked} onChange={this.handleClick}/>
</div>
)
}
}
ReactDOM.render(<AppInput />,document.getElementById('root'))
高阶函数
如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数.
- 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
- 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数 函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式.
非受控组件
借助于ref,使用原生DOM方式来获取表单元素值 ref作用:获取DOM或组件
class APPRef extends React.Component{
constructor(){
super()
// 创建ref对象
this.txtRef = React.createRef()
}
getTxt=()=>{
console.log('文本框值为',this.txtRef.current.value)
}
render(){
return(
<div>
<input type="text"ref = {this.txtRef}/>
<button onClick= {this.getTxt}>获取文本信息</button>
</div>
)
}
}
ReactDOM.render(<APPRef />,document.getElementById('root'))