React 组件创建 生命周期 PropTypes

组件创建

第一种方式
import React from 'react';
import ReactDOM from 'react-dom';

// 第一种创建组件,props可以是其他,形参,但这样语义化
// 首字母大写
function HelloWorld(props){
    console.log(props)
    // props.name="Li Mei"  props只读,会报错

    // return null
    return <div>这是一个HelloWorld组件---大家好,我叫{props.name},今年我{props.age}</div>
}

const man = {
    name:"David",
    age:"19",
    gender:"man"
}
// {...man} 展开运算符
ReactDOM.render(<HelloWorld name = {man.name} age = {man.age} gender = {man.gender}></HelloWorld>,document.getElementById('root'))

// 展开运算符
var object1 = {
    data:"1",
    name:"Li Mei",
    age:"18"
}

var object2 = {
    gender:"男",
    ...object1
}


console.log(object2,"object3")




单独把组件拎出来

import React from 'react';

// 第一种创建组件,props可以是其他,形参,但这样语义化   只读
export default function HelloWorld(props){
    console.log(props,"props")
    // props.name="Li Mei"

    // return null
    return <div>这是一个HelloWorld组件---大家好,我叫{props.name},今年我{props.age}</div>
}

引用组件时,记得import,后缀名要一致,可以jsx,或者js。有坑
import 文件时,若创建文件以.jsx结尾时,能省去。若创建文件以.js结尾时,就不能省去。(可能是react-app中webpack的规则问题,没找到位置,有知道的望告之)

第二种方式

  • 使用class关键字创建组件
    • 实例属性
    • 静态属性
// 以前新建某某实例,以构造函数形式,
function Person(name,age){
   this.name = name
   this.age = age
}
Person.info = "我是一条信息"
var P1 = new Person("David",18)
console.log(P1)

// 通过new实例创建的构造函数或者类,叫做 实例属性
// P1.name  P1.age 即是实例属性
// 通过 构造函数直接访问的属性,叫做静态属性
// info 即是静态属性,不需要new




// 新建数组是不是也是 new 一下


// 创建一个类
class Person {
        // 每个类都有一个构造器,哪怕没写,默认内部有个隐形空构造器
        //构造器的作用:new 实例的时候,先执行构造器中的代码
    constructor(name,age){
        this.name = name
        this.age = age
    }
    // 静态属性 访问 Person.info
    static info = "我是一条static信息"
}

const p2 = new Person("David",18)

// 通过new实例创建的构造函数或者类,叫做 实例属性
// 通过 构造函数,直接访问的属性,叫做静态属性
// 这里name age 也是实例属性
  • 实例方法
  • 静态方法
// 原型,节约内存
Person.prototype.say = function(){
    console.log("实例方法")
}

P1.say()  // 实例方法

Person.key = function(){
    console.log("静态方法")
}
Person.key()


    // 实例方法和静态方法
    say(){

    }
    static say(){

    }
    // 静态属性和方法都会挂载到constructor,不在原型对象上面 ,有截图

在这里插入图片描述
注意:

  • class { } 只能写构造器,静态方法与属性,实例方法
  • class 语法糖

class继承

class Person {
    constructor(name,age){
        this.name = name
        this.age = age
    }
    say(){
    	console.log("我是一个实例方法,原型,公共")
    }
}
// 在class中,可以用extends实现继承
class Chinese extends Person{
	// 在构造器中加 super() name  age 为undefined 
	// 下面是正确写法
	    constructor(name ,age){
	    super(name,age)
	    //  this....
    }
}
var a = new Chinese("jack" ,18)
console.log(a)

super

  • 为什么要调用super()
    • 子类通过extends关键字继承父类,那么,在子类的constructor 构造函数中,必须优先调用 super()
  • super
    • super是一个函数,而且是父类的构造器,子类中的 super,其实是父元素constructor构造器的引用
基本构建
import React, { Component } from 'react';
// React.Component
class App extends Component {
    constructor(){
	    super()
	    this.state = { }
    }
  render() {
    return (
      <div >
      。。。。
      </div>
    );
  }
}

两种创建组件方式

  • 没多少区别,关键在于class创建的组件有私有数据(state)和生命周期,function创建的则没有,只有props
  • 构造函数 为 无状态组件 class 为 有状态组件(如果组件里只有render,也是无状态组件)
    没有特殊要求,无状态组件性能比较好

state

  • this.state={} 类似于Vue中 data
  • 读取 this.state.msg
  • 修改 this.setState.msg

props和state

  • props中的数据是外界传递过来的,只读
  • state/data中的数据是组件私有,可读可写
  • 读写 其实是set 和 get 属性控制

React 生命周期

生命周期函数

组件加载之前,组件加载完成,以及组件更新数据,数据销毁

组件加载的时候触发的函数
  • constructor
  • componentWillMount
  • render
  • componentDidMount(通常页面初次渲染,方法在此调用,dom操作)
组件更新的时候触发的函数
  • shouldComponentUpdata( nextProps,nextState ){ return true}
    • 判断是否更新数据
  • componentWillUpdata
  • render
  • componentDidMount
组件将要卸载的函数
  • componentWillUnmount
父组件改变props值
  • componentWillReceiveProps

先componentWillReceiveProps,后shouldComponentUpdata

PropTypes

详情看官网
import PropTypes from 'prop-types';  // 限制组件/容器中属性
MyComponent.propTypes = {
  // 你可以将属性声明为以下 JS 原生类型
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 任何可被渲染的元素(包括数字、字符串、子元素或数组)。
  optionalNode: PropTypes.node,

  // 一个 React 元素
  optionalElement: PropTypes.element,

  // 你也可以声明属性为某个类的实例,这里使用 JS 的
  // instanceof 操作符实现。
  optionalMessage: PropTypes.instanceOf(Message),

  // 你也可以限制你的属性值是某个特定值之一
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // 限制它为列举类型之一的对象
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // 一个指定元素类型的数组
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // 一个指定类型的对象
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // 一个指定属性及其类型的对象
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),

  // 你也可以在任何 PropTypes 属性后面加上 `isRequired` 
  // 后缀,这样如果这个属性父组件没有提供时,会打印警告信息
  requiredFunc: PropTypes.func.isRequired,

  // 任意类型的数据
  requiredAny: PropTypes.any.isRequired,

  // 你也可以指定一个自定义验证器。它应该在验证失败时返回
  // 一个 Error 对象而不是 `console.warn` 或抛出异常。
  // 不过在 `oneOfType` 中它不起作用。
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

  // 不过你可以提供一个自定义的 `arrayOf` 或 `objectOf` 
  // 验证器,它应该在验证失败时返回一个 Error 对象。 它被用
  // 于验证数组或对象的每个值。验证器前两个参数的第一个是数组
  // 或对象本身,第二个是它们对应的键。
  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};

defaultProps
class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// 为属性指定默认值:
Greeting.defaultProps = {
  name: 'Stranger'
};

// 渲染 "Hello, Stranger":
ReactDOM.render(
  <Greeting />,
  document.getElementById('example')
);

如果有问题,望斧正,也欢迎交流,共同脱坑

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值