Front-end/react/3.react组件.md

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文件

  1. 创建HelloRender.js文件
  2. 在HelloRender.js文件中导入React
  3. 创建组件
  4. 在HelloRender.js中导出该组件
  5. 在index.js中导入HelloRender组件
  6. 渲染组件
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指向

  1. 箭头函数,利用箭头函数自身不绑定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'))
  1. 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'))
  1. 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.

事件处理

  1. 通过onXxx属性指定事件处理函数,必须驼峰
    1. React使用的是自定义合成事件,而不是使用原生DOM事件,为了更好兼容性
    2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素),为了更高效
  2. 可以通过event.target得到发生事件的DOM元素对象,避免过度使用ref

表单处理

受控组件,其值受到React控制的表单元素

  1. html中表单元素是可输入的,也就是有自己的可变状态
  2. react中可变状态通常通过state处理,并且只能通过setState()来处理
  3. react将state与表单元素值value绑定到一起,由state的值来控制表单元素的值
  4. 类似vue中双向绑定

使用步骤

  1. 在state中添加一个状态,作为表单元素的value值(控制表单元素的来源)
  2. 给表单元素绑定change事件,将表单元素的值设置为state值(控制表单元素值的变化)

使用一个事件处理程序同时处理多个表单元素

  1. 给表单添加一个name属性,名称与state相同
  2. 根据表单元素类型获取对应值
  3. 在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个规范中的任何一个,那该函数就是高阶函数.

  1. 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
  2. 若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'))