react核心概念--组件

命名规则

组件名首字母必须大写
如果首字母小写的话,会被当成一个html标签其解析,而不是一个组件

function MyFuncComp1() {
  return <h1>组件内容1</h1>
}
const comp = <MyFuncComp1 />;
console.log(comp)
function myFuncComp2() {
  return <h1>组件内容2</h1>
}
const comp2 = <myFuncComp2 />;
console.log(comp2)

在这里插入图片描述

组件类型

函数组件

返回一个React元素

import React from 'react';
import ReactDOM from 'react-dom';
// 组件名首字母必须大写
// 函数组件要返回react元素
function MyFuncComp() {
  // return React.createElement(...)
  return <h1>组件内容</h1>
}
ReactDOM.render(
  <div>
  {/* {MyFuncComp()} */}//这种方式并没有体现出组件
  	<MyFuncComp/>
  </div>, 
  document.getElementById("root")
);

类组件

必须继承React.Component
必须提供render函数,用于渲染组件

import React, { Component } from 'react'
// 导出一个类,这个类继承react的Component,且必须有render函数
export default class MyClassComp extends Component {
  // 必须返回一个React元素
  render() {
    return <h1>组件内容</h1>
  }
}

组件的属性

对于函数组件,属性会作为一个对象的属性,传递给函数的参数
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
对于类组件,属性会作为一个对象的属性,传递给构造函数的参数
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
注意:组件的属性,应该使用小驼峰命名法

import React, { Component } from 'react'
// 导出一个类,这个类继承react的Component,且必须有render函数
export default class MyClassComp extends Component {
  constructor(props) {
    super(props)
    console.log(props)
  }
  // 必须返回一个React元素
  render() {
    if (this.props.obj) {
      return (
        <div style={{
          width: '100%',
          height: '100px',
          background: 'rgb(224, 219, 219)'
        }}>
          <p>姓名:{this.props.name}</p>
          <p>性别:{this.props.obj.sex}</p>
          <p>年龄:{this.props.obj.age}</p>
        </div>
      )

    } else if (this.props.em) {
      return (
        <div style={{
          width: '100%',
          height: '100px',
          background: 'rgb(224, 229, 229)'
        }}>
          <h1>下面是传入的内容</h1>
          {this.props.em}
        </div>
      );
    }
    return <h1>类组件内容,名字叫{this.props.name}</h1>
  }
}

在这里插入图片描述
组件无法改变自身的属性。

之前学习的React元素,本质上,就是一个组件(内置组件)

React中的哲学:数据属于谁,谁才有权力改动

React中的数据,自顶而下流动,单向数据流

组件状态

组件状态:组件可以自行维护的数据;
状态(state):本质上是类组件的一个属性,是一个对象

组件状态仅在类组件中有效,函数组件通过hooks来使用组件状态

状态初始化

  • 在构造函数中初始化
constructor(props) {
    super(props)
    // 状态初始化
    this.state = {
      initData: this.props.time
    }
  }

状态的变化

不能直接改变状态this.state.initData--;:因为React无法监控到状态发生了变化;必须使用this.setState({})改变状态this.setState()来自父组件;一旦调用了this.setState,会导致当前组件重新渲染

//这里会将之前的数据覆盖,其实就是Object.assign(this.state.initData,initData),
this.setState({
        initData: this.state.initData - 1
      });

组件中的数据

props:该数据是由组件的使用者传递的数据,所有权不属于组件自身,因此组件无法改变该数组
state:该数组是由组件自身创建的,所有权属于组件自身,因此组件有权改变该数据

组件事件

在React中,组件的事件,本质上就是一个属性;按照之前React对组件的约定,由于事件本质上是一个属性,因此也需要使用小驼峰命名法

常规使用

import React from 'react'
import ReactDOM from 'react-dom'

//function handleClick(e) {
  //console.log("再点我我就生气了", e)
//}
// const btn = <button onClick={handleClick}>快点我!</button>
const btn = <button onClick={() => {
  console.log("再点我我就生气了!")
}}>快点我!</button>
ReactDOM.render(btn, document.getElementById("root"));

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

注意

在这里插入图片描述
如果想要实现点击效果,应该在使用者的内置组件中调用

this指向

问题

如果没有特殊处理,在事件处理函数中,this指向undefined
<Tick onclick={this.handleOnClick} onOver={this.handleOnOver} time={10} />

  handleOnOver() {
    //这里的this就是undefined
    this.setState({
      isOver: true
    })
  }

处理方式

  • 使用bind函数,绑定this
  constructor(props){
         super(props);
         this.handleClick = this.handleClick.bind(this);
         this.handleOver = this.handleOver.bind(this);
     }

或者<Tick onClick={this.handleClick.bind(this)} onOver={this.handleClick.bind(this)} number={10} />

  • 使用箭头函数
 // 结果:handleClick不在原型上,而在对象上
    handleClick = () => {
        console.log(this)
        console.log("点击了")
    }

    handleOver = () => {
        this.setState({
            isOver: true
        })
    }

setState,它对状态的改变,可能是异步的
如果改变状态的代码处于某个HTML元素的事件中,则其是异步的,否则是同步(定时器用的是setInterval,不是html元素事件
如果遇到某个事件中,需要同步调用多次,需要使用函数的方式得到最新状态

最佳实践:
把所有的setState当作是异步的
永远不要信任setState调用之后的状态
如果要使用改变之后的状态,需要使用回调函数(setState的第二个参数)
如果新的状态要根据之前的状态进行运算,使用函数的方式改变状态(setState的第一个函数)
React会对异步的setState进行优化,将多次setState进行合并(将多次状态改变完成后,再统一对state进行改变,然后触发render)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值