react组件

React组件

React组件介绍

  • 组件是React的一等公民,使用React就是在用组件
  • 组件表示页面中的部分功能
  • 组合多个组件实现完整的页面功能
  • 特点:可复用、独立、可组合

React组件的两种创建方式

    1. 使用函数创建组件

      • 函数组件:使用JS的函数(或箭头函数)创建的组件

      • 约定1:函数名称必须以大写字母开头,React据此区分组件和普通的React元素

      • 约定2:函数组件必须有返回值,表示该组件的结构

      • 如果返回值为null,表示不渲染任何内容

      • 渲染函数组件:用函数名作为组件标签名

      • 组件标签可以是单标签也可以是双标签

      • 示例:

        const Hello = () => (<div>这是我的第一个函数组件!!!</div>)
        
    2. 使用类创建组件

      • 类组件:使用ES6 的class创建的组件

      • 约定1:类名称也必须以大写字母开头

      • 约定2:类组件应该继承React.Component父类,从而可以使用父类中提供的方法或属性

      • 约定3:类组件必须提供render()方法

      • 约定4:render()方法必须有返回值,表示该组件的结构

      • 示例:

        class Hello extends React.Component {
            render() {
                return (
                    <div>这是我的第一个类组件!!!</div>
                )
            }
        }
        // 渲染组件
        ReactDOM.render(<Hello />, document.getElementById('root'))
        
    3. 抽离为独立JS文件

      • 1、创建Hello.js

      • 2、在Hello.js中导入React

      • 3、创建组件(函数或类)

      • 4、在Hello.js中导出该组件

      • 5、在index.js中导入Hello组件

      • 6、渲染组件

      • 示例:

        // Hello.js
        import React from "react";
        
        
        class Hello extends React.Component{
            render() {
                return (
                    <div>第一个抽离的组件</div>
                )
            }
        }
        
        export default Hello
        
        
        // index.js
        import Hello from "./Hello";
        ReactDOM.render(<Hello />, document.getElementById('root'))
        

React事件处理

  • 事件绑定

    • React事件绑定语法与DOM事件语法相似

    • 语法:on+事件名称={事件处理程序},比如:onClick={()=>{}}

    • 注意:React事件采用驼峰命名法,比如onMouseEnter、onFocus

    • 示例:

      // 方式一,使用class
      class App extends React.Component {
          handleClick(){
              console.log('点击成功')
          }
          render() {
              return (
                  <button onClick={this.handleClick}>点我</button>
              )
          }
      }
      
      // 方式一,使用函数
      function App() {
          function handleClick(){
              console.log('点击成功')
          }
          return (
              <button onClick={handleClick}>点我</button>
          )
      }
      
      
      ReactDOM.render(<App/>, document.getElementById('root'))
      
  • 事件对象

    • 可以通过事件处理程序的参数获取到事件对象

    • React中的事件对象叫做:合成事件(对象)

    • 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题

    • 示例:

      class App extends React.Component{
          handleClick(e){
              // 阻止浏览器行为
              e.preventDefault()
              console.log('阻止浏览器行为')
          }
          render() {
              return (
                  <a href="https://www.baidu.com/" onClick={this.handleClick}>百度</a>
              )
          }
      }
      
      ReactDOM.render(<App/>, document.getElementById('root'))
      

有状态组件与无状态组件

  • 函数组件又叫做无状态组件,类组件又叫做有状态组件
  • 状态(state)即数据
  • 函数组件没有自己的状态,只负责数据展示(静)
  • 类组件有自己的状态,负责更新UI,让页面“动”起来

组件中的state和setState()

  • state的基本使用

    • 状态(state)即数据,是组件内部的私有数据,只能在组件内部使用

    • state的值是对象,表示一个组件中可以有多个数据

    • 通过this.state 来获取状态

    • 示例:

      class App extends React.Component {
          // constructor() {
          //     super();
          //     this.state = {
          //         count: 0
          //     }
          // }
          // 精简版
          state = {
              count: 0
          }
      
          render() {
              return (
                  <div>有状态组件, {this.state.count}</div>
              )
          }
      
      }
      ReactDOM.render(<App/>, document.getElementById('root'))
      
  • setState()修改状态

    • 状态是可变的

    • 语法:this.setState({要修改的数据})

    • 注意:不要直接修改state中的值,这是错误的!!!

    • setState()作用:1.修改state 2.更新UI

    • 思想:数据驱动视图

    • 示例:

      class App extends React.Component {
      
          state = {
              count: 0,
              test: 'a'
          }
      
          render() {
              return (
                  <div>
                      <h1>计数器: {this.state.count}</h1>
                      <button onClick={
                          ()=> {
                              this.setState({
                                  count: this.state.count + 1
                              })
      
                              // 错误示例
                              // this.state.count += 1
                          }
                      }>+1
                      </button>
                  </div>
              )
          }
      
      }
      ReactDOM.render(<App/>, document.getElementById('root'))
      
      
  • 从JSX中抽离事件处理程序

    • JSX中掺杂过多JS逻辑代码,会显得非常混乱
    • 推荐:将逻辑抽离到单独的方法中,保证JSX结构清晰
    • 报错原因:事件处理程序中this的值为undefined
    • 希望:this指向组件实例(render方法中的this即为组件实例)

事件绑定this指向

  • 1.箭头函数

    • 利用箭头函数自身不绑定this的特点

    • render()方法中的this为组件实例,可以获取到setState()

    • 示例:

      class App extends React.Component {
      
          state = {
              count: 0
          }
          onIncrement(){
              console.log(this)
              this.setState({
                  count: this.state.count + 1
              })
          }
      
          render() {
              return (
                  <div>
                      <h1>计数器: {this.state.count}</h1>
                      <button onClick={() => this.onIncrement()}>
                          +1
                      </button>
                  </div>
              )
          }
      
      }
      ReactDOM.render(<App/>, document.getElementById('root'))
      
  • 2.Function.prototype.bind()

    • 利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到一起

    • 示例:

      class App extends React.Component {
          constructor() {
              super();
              this.state = {
                  count: 0
              }
              this.onIncrement = this.onIncrement.bind(this)
          }
      
          onIncrement(){
              console.log(this)
              this.setState({
                  count: this.state.count + 1
              })
          }
      
          render() {
              return (
                  <div>
                      <h1>计数器: {this.state.count}</h1>
                      <button onClick={this.onIncrement}>
                          +1
                      </button>
                  </div>
              )
          }
      
      }
      ReactDOM.render(<App/>, document.getElementById('root'))
      
  • 3.class的实例方法

    • 利用箭头函数形式的class实例方法

    • 注意:该语法是实验性语法,但是,由于babel的存在可以直接使用

    • 示例:

      class App extends React.Component {
          state = {
              count: 0
          }
      
          onIncrement = () => {
              console.log(this)
              this.setState({
                  count: this.state.count + 1
              })
          }
      
          render() {
              return (
                  <div>
                      <h1>计数器: {this.state.count}</h1>
                      <button onClick={this.onIncrement}>
                          +1
                      </button>
                  </div>
              )
          }
      
      }
      ReactDOM.render(<App/>, document.getElementById('root'))
      

表单处理

  • 1.受控组件

    • HTML中的表单元素是可输入的,也就是自己的可变状态

    • 而,React中可变状态通常保存在state中,并且只能通过setState()方法来修改

    • React将state与表单元素值value绑定在一起,由state的值来控制表单元素的值

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

    • 示例:

      <input type="text" value={this.state.txt} />
      
    • 步骤:

      • 1.在state中添加一个状态,作为表单元素的value值(控制表单元素的来源)

      • 2.给表单元素绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)

      • 示例:

        class App extends React.Component{
            state = {
                txt: ''
            }
            handleChange = (e) => {
                this.setState({
                    txt: e.target.value
                })
            }
        
            render() {
                return (
                    <div>
                        <input type="text" value={this.state.txt}
                               onChange={this.handleChange}
                        />
                    </div>
                )
            }
        }
        ReactDOM.render(<App/>, document.getElementById('root'))
        
      • 示例总结:

        • 文本框、富文本框、下拉框 操作value属性

        • 复选框 操作checked属性

        • 示例:

          class App extends React.Component{
              state = {
                  txt: '',
                  content: '',
                  city: 'bj',
                  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}
                          />
                          <br/>
          
                          {/*富文本框 */}
                          <textarea value={this.state.content} onChange={this.handleContent}/>
                          <br/>
          
                          {/*下拉框 */}
                          <select value={this.state.city} onChange={this.handleCity}>
                              <option value="sh">上海</option>
                              <option value="bj">北京</option>
                              <option value="nj">南京</option>
                          </select>
                          <br/>
          
                          {/*复选框 */}
                          <input type="checkbox" checked={this.state.isChecked} onChange={this.handleChecked}/>
          
                      </div>
                  )
              }
          }
          ReactDOM.render(<App/>, document.getElementById('root'))
          
      • 多表单元素优化:

        • 问题:每个表单元素都有一个单独的事件处理程序处理太繁琐

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

        • 优化步骤:

          • 1.给表单元素添加name属性,名称与state相同

          • 2.根据表单元素类型获取对应值

          • 3.在change事件处理程序中通过[name]来 修改对应的state

          • 示例:

            class App extends React.Component{
                state = {
                    txt: '',
                    content: '',
                    city: 'bj',
                    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}
                            />
                            <br/>
            
                            {/*富文本框 */}
                            <textarea name="content" value={this.state.content} onChange={this.handleForm}/>
                            <br/>
            
                            {/*下拉框 */}
                            <select name="city" value={this.state.city} onChange={this.handleForm}>
                                <option value="sh">上海</option>
                                <option value="bj">北京</option>
                                <option value="nj">南京</option>
                            </select>
                            <br/>
            
                            {/*复选框 */}
                            <input type="checkbox" name="isChecked" checked={this.state.isChecked} onChange={this.handleForm}/>
            
                        </div>
                    )
                }
            }
            ReactDOM.render(<App/>, document.getElementById('root'))
            
    • 2.非受控组件

      • 说明:借助于ref,使用原生DOM方式来获取表单元素值

      • ref的作用:获取DOM或组件

      • 步骤:

        • 1.调用React.createRef()方法创建一个ref对象

        • 2.将创建好的ref对象添加到文本框中

        • 3.通过ref对象获取到文本框的值

        • 示例:

          class App extends React.Component {
              constructor() {
                  super();
          
                  // 创建ref
                  this.txtRef = React.createRef()
              }
          
              // 获取文本框的值
              getTxt = () => {
                  console.log('打印')
                  console.log(this.txtRef.current.value)
              }
          
              render() {
                  return (
                      <div>
                          {/*文本框 */}
                          <input type="text" ref={this.txtRef} />
                          <button onClick={this.getTxt}>获取文本框的值</button>
                      </div>
                  )
              }
          }
          
          ReactDOM.render(<App/>, document.getElementById('root'))
          
原文地址:https://www.cnblogs.com/ghh520/p/15088281.html