React组件基础(一)

React组件介绍

组件是Reat的一等公民,使用 React就是在用组件组件表示页面中的部分功能,组合多个组件实现完整的页面功能。

特点:可复用、独立、可组合

React创建组件的两种方式

使用函数创建组件

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

  • 约定一:函数名称必须以大写字母开头
  • 约定二:函数组件必须有返回值,表示该组件的结构
    • 如果返回null,表示不渲染任何内容
// 函数组件
function Hello() {
 return (
	 <div>这是一个组件</div>
 )
}

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

ReactDOM.render(<Hello/>, document.getElementById('root'))

使用类创建组件

使用ES6的 class 关键字创建组件:

  • 约定一:类名称也必须以大写字母开头
  • 约定二:类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法或属性。
  • 约定三:类组件必须提供 render() 方法
  • 约定四:render()方法必须有返回值,表示为该组件的结构
class Hello extends React.Component{
 render() {
 return <h1>hello</h1>
 }
}

ReactDOM.render(<Hello/>, document.getElementById('root'))

抽离为单独的JS文件

新建一个js文件,然后再该文件中导入React,接着创建组件(函数或者类),最后导出组件即可。

输入rcc敲下回车,可以快速创建 react class component。

// Hello.js
import React from 'react';

// 创建组件
class Hello extends React.Component{
  render() {
    return (
      <div>
        hi,我是一个组件
      </div>
    )
  }
}

// 导出组件
export default Hello;
// 导入组件

import Hello from './Hello';
ReactDOM.render(<Hello/>, document.getElementById('root'))

React 事件处理

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

  • 语法:on+事件名称={事件处理程序},比如:onClick={()=>{}}
  • 注意:React事件采用驼峰命名法,比如:onMouseEnter、 onFocus
// 类组件
class App extends React.Component{
 // 事件处理程序
 handleClick() {
	 console.log('单击事件触发了');
 }
 render() {
	 return <button onClick={this.handleClick}>点我点我</button>
 }
}
//函数组件绑定事件
function App2() {
  function click() {
    console.log('I got clicked');
  }
  return <button onClick={click}>Click ME</button>
}

事件对象

  • 可以通过事件处理程序的参数获取到事件对象
  • React中的事件对象叫做:合成事件(对象)
  • 合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
// React事件对象
class App extends React.Component{
  handleClick(e) {
    e.preventDefault();
    
  }
  render() {
    return (<a href='https://jiaqicoder.com' onClick={this.handleClick}>click me</a>);
  }
}

有状态组件和无状态组件

函数组件又叫做无状态组件,类组件又叫做有状态组件。

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

比如计数器案例中,点击按钮让数值加1。0和1就是不同时刻的状态,而由0变为1就表示状态发生了变化。状态变化后,UI也要相应的更新。 React中想要实现该功能,就要使用有状态组件来完成。

state和setSate

a. state

状态( state)即数据,是组件内部的私有数据,只能在组件内部使用。state的值是对象,表示一个组件中可以有多个数据。

// state的基本使用
class App extends React.Component{
  // 方式一:
  // constructor() {
  //   super();
  //   // 初始化state
  //   this.state = {
  //     count:0,
  //   };
  // }
  // 方式二:
  state = {
    count:0,
  }
  render() {
    return <div><h1>计数器:{ this.state.count}</h1></div>
  }
}
  • 状态即数据
  • 状态是私有的,只能在组件内部使用
  • 通过this.state来获取状态

b. setState()修改状态

  • 状态是可变的
  • 语法:this.setState({要修改的数据})
  • 注意:不要直接修改state中的数据,这是错误的。
  • setState()的作用:1. 修改state 2.更新UI
  • 思想:数据驱动视图
class App extends React.Component {
  state = {
    count: 0,
  }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={() => { this.setState({ count: this.state.count + 1 }) }}> 加一</button>
      </div>)
  }
}

从JSX中抽离事件处理程序

  • JSX中掺杂过多JS逻辑代码,会显得非常混乱
  • 推荐:将逻辑抽离到单独的方法中,保证JSX结构清晰
class App extends React.Component {
  
  state = {
    count: 0,
  }
  // 事件处理程序
  add() {
     console.log(this);
   }
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.add}> 加一</button>
      </div>)
  }
}

但是事件处理程序中this的值为 undefined,但是我们希望this指向组件实例( render方法中的ths即为组件实例)。

解决办法:

  1. 箭头函数

    使用箭头函数让 this.add 指向上一级作用域,也就是指向render函数。

    class App extends React.Component {
      state = {
        count: 0,
      }
      // 事件处理程序
      add() {
         console.log(this);
       }
      render() {
    	//箭头函数中的this指向外部环境,此处为render()方法
        return (
          <div>
            <h1>计数器:{this.state.count}</h1>
            <button onClick={()=>this.add()}> 加一</button>
          </div>)
      }
    }
    
  2. Function.prototype.bind()

    • 利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到起
    class App extends React.Component {
      constructor() {
        super();
    	this.state = {count: 0};
        this.add = this.add.bind(this);
      }
      // 事件处理程序
      add() {
        this.setState({
          count: this.state.count + 1
        })
      }
      render() {
        return (
          <div>
            <h1>计数器:{this.state.count}</h1>
            <button onClick={this.add}> 加一</button>
          </div>)
      }
    }
    
  3. class的实例方法

    • 利用箭头函数形式的class实例方法
    • 注意:该语法是实验性语法,但是,由于 babel的存在可以直接使用
    class App extends React.Component {
    
      state = {
        count: 0,
      }
      
      // 事件处理程序
      add=()=> {
        this.setState({
          count: this.state.count + 1
        })
      }
      render() {
        return (
          <div>
            <h1>计数器:{this.state.count}</h1>
            <button onClick={this.add}> 加一</button>
          </div>)
      }
    }
    

表单处理

受控组件

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

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

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

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

    state = {txt:''}
    
    <input type='text' value = {this.state.txt} />
    
  2. 给表单元素绑定 change 事件,将表单元素的值设置为 state 的值(控制表单元素值的变化)

    <input type='text' value = {this.state.txt} 
    	   onChange = { e => this.setState({txt: e.target.value}) }/>
    
文本框,多行文本,下拉框,复选框

文本框,多行文本,下拉框操作的是 value 属性,而复选框操作的是 checked 属性。

class App extends React.Component {
  state = {
    txt: '',
    content: '',
    city: 'bj',
    isChecked: true,
  }
  handleChange = (e) => {
    this.setState({
      txt: e.target.value,
    })
  }
  // 处理富文本框的变化
  handleContent = (e) => {
    this.setState({
      content: e.target.value,
    })
  }
  // 处理下拉框的变化
  handleCity = (e) => {
    this.setState({
      city: e.target.value,
    })
  }
  // 处理复选框的变化
  handleCheck = (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}></textarea>
        <br />
        {/* 下拉框 */}
        <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.handleCheck} />
      </div>
    )
  }
}

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

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

方法

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

    <input type='text' name='txt' value = {this.state.txt} onChange = {this.handleForm}/>
    
  2. 根据表单元素类型获取相对应的值

    const target = e.target;
    //根据表单元素获取相对应的值
    const value = target.type ==='checkbox' ? target.checked: target.value
    //根据名称name设置对应的state
    this.setState({
    	[target.name]: value
    })
    
    // 多表单组件的优化
    class App extends React.Component {
      state = {
        txt: '',
        content: '',
        city: 'bj',
        isChecked: true,
      }
      handleChange = (e) => {
        const target = e.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        this.setState({
          [target.name]: value
        })
      }
    
      render() {
        return (
          <div>
            {/* 文本框 */}
            <input type="text" name='txt' value={this.state.txt} onChange={this.handleChange} />
            <br />
            {/* 富文本框 */}
            <textarea name='content' value={this.state.content} onChange={this.handleChange} ></textarea>
            <br />
            {/* 下拉框 */}
            <select name='city' value={this.state.city} onChange={this.handleChange} >
              <option value="sh">上海</option>
              <option value="bj">北京</option>
              <option value="gz">广州</option>
            </select>
            {/* 复选框 */}
            <input type="checkbox" name='isChecked' checked={this.state.isChecked} onChange={this.handleChange} />
          </div>
        )
      }
    }
    

非受控组件

  • 借助于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();
      }
      // 获取文本框的值
      getTxt = () => {
        console.log(this.txtRef.current.value);
      }
      render() {
        return (
          <div>
            <input type="text" ref={this.txtRef} />
            <button onClick={this.getTxt}>click me</button>
          </div>
        )
      }
    }
    

笔记基于:React视频

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值