React2——函数组件与class组件

函数组件

  • 是一种无状态组件,因此不存在state
  • props是形参,使用props可以为该组件进行传值操作
  • 组件名首字母必须大写,否则使用无效

将组件抽离到单独的jsx文件时:

// public.jsx
import React from 'react'


function Com (props) {
    return <div className="message">姓名:{props.name}年龄:{props.age}身高:{props.tall}体重:{props.weight}</div>;
    }
export {Com}

// index.js
import {Com} from './public.jsx'
const message = {
    name: 'mob',
    age: 18,
    tall: 180,
    weight: 150
}
// 下面是两种写法

// 这样列举每个属性作为参数比较麻烦
ReactDom.render(
<div><Com name = {message.name} age = {message.age} tall = {message.tall} weight = {message.weight}></Com></div>,
document.getElementById("live"))

// 可以简写成扩展运算符的形式
ReactDom.render(
<div><Com {...message}/></div>,
document.getElementById("live"))

class组件

  • state进行写操作时,不要使用赋值的手段,而是要借助this.setState()方法进行

  • 需要注意this.statethis.props可能是异步更新的,因此不能依赖它们的值去计算下一个state,但是可以利用this.setState((prevState, props)=> ({}));的参数

  • return函数内需要返回一个合法的jsx虚拟DOM结构,如果没有需要返回的DOM结构, 直接return null即可

  • 绑定事件方法时需注意(受控组件)

  • 如果没有私有数据的话,可以不写constructor部分,只写render即可

// class关键字创建组件
class Son extends React.Component {
    // 绑定私有属性
    constructor (props) {
        super(props)
        // 里边可以写私有属性,相当于vue的data
        this.state = {
            stand: 'soft & wet'
        }
    }

    // render用来渲染当前组件对应的虚拟DOM元素
    render() {  
        // state值可读可写 不推荐使用赋值的方法去执行写操作
        this.setState({stand: 'bed'});
      // 使用解构赋值的方法可以避免大量重复代码
      	let { love, feel, stand } = this.props;
        // render函数内必须返回一个合法的jsx虚拟DOM结构  
        return <div className="mes">
            {/* 在class组件内部,this表示当前组件的实例对象 */}
            Return To Innocence----Son likes { love } so he feels { feel }
    ----- and his stand is { stand }
            </div>
            // return null
        }
} 

事件处理函数的this绑定

class组件默认不会绑定this,忘记手动绑定时this为undefined

可以采用两种方法来绑定this以及借助箭头函数避免this绑定

// 第一种方法:
// class->constructor

this.handleClick = this.handleClick.bind(this);

// Class->render

button = <LogoutButton onClick={this.handleLogoutClick} />;

// 第二种方法:

class LoggingButton extends React.Component {

 handleClick() {

  console.log('this is:', this);

 }

 render() {

  // 此语法确保 `handleClick` 内的 `this` 已被绑定。

  return (

   <button onClick={(e) => this.handleClick(e)}>

    Click me

   </button>

  );
 }
}

以上两种方式都可以向事件处理函数传递参数:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>

<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

如果使用箭头函数:(更简洁简单)

class SelectOperation extends React.Component {
  constructor (props) {
        super(props)
        // 里边可以写私有属性,相当于vue的data
        this.state = {
            ......
        }
    }
  
  onChangeSelect = e => {
    this.setState({
      name: e.target.name, 
      val: e.target.value
    });
  };
  
  render () {
    let { val } = this.state;
   return (
          <input type="text"
          onChange = {this.onChangeSelect} 
          value = {val}
          ></input>
      </Form>
    ) 
  };  
};

另外注意⚠️:

  1. setState() 可以接收对象也可以接收函数
  • 当setState() 传对象类型参数,React会合并重复多次的调用setState(),触发一次render。
  • 当setState() 传函数类型参数,React会依次多次的调用setState(),触发一次render。
  1. react推崇自顶向下的数据流向 即组件的数据由父组件传递给子组件,反向传递则需要使用回调函数的方式

总结:

  1. 在两种创建组件的方法中,props都是只读的
  2. 参数访问方式略微不同
  3. 用class创建的组件,有自己的私有数据(即有状态)和生命周期函数,但是function创建的没有(无状态)

使用组件会发生什么?

  1. 调用ReactDOM.render,传入自定义组件
  2. 调用组件,传入实参
  3. 组件返回
  4. React DOM 将 DOM 高效地更新

你可能感兴趣的:(react)