react(三)组件、事件

组件的状态

组件都可以自行的维护自己的数据,尽量在内组件中使用
状态:本质上就是类组件的一个属性,就是一个对象

状态的初始化:
constructor 中 this.state = {}
类中 state = {} jsnext语法,试验阶段,都可以写,最后都要被babel编译

状态的变化:
不能直接去改变状态中的数据,因为react无法监控到状态中数据的变化,必须使用this.setState({})改变数据,如果对比数据变化,则不会动对象,考虑效率。一旦使用this.setState,会导致当前的组件重新渲染

组件中的数据
props 组件之间传递的数据,所有权是别人,没有权利更改
state 组件自己本身创建的数据,所有权是自己,有权利更改

下面写的是一个小dome
见代码:

import React from 'react';
import ReactDOM from 'react-dom';
import Tndexaa from './Tndexaa';

ReactDOM.render(<Tndexaa number={20}></Tndexaa>, document.getElementById('root'));
import React, { Component } from 'react'

export default class Tndexaa extends Component {

    state = {  //js next语法,目前处于试验阶段
        left : this.props.number
    }

    // 1.接收数据
    constructor(props){
        super(props);
        // 状态的初始化
        this.state = {
            left : this.props.number
        }
        this.timer = setInterval(() => {
            // react中要修改组件的数据
            this.setState({
                // minix 混合  有相同的就覆盖   相当于object.assign()
                left : this.state.left -1
            })
            if(this.state.left == 0){
                clearInterval(this.timer)
            }
        },1000)
    }
    render() {
        return (
            <div>
                倒计时剩余时间{this.state.left}
            </div>
        )
    }
}

再看一个栗子:

import React from 'react';
import ReactDOM from 'react-dom';
import Tndexbb from './Tndexbb';

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

import React, { Component } from 'react'

export default class Tndexbb extends Component {
    state = {
        n : 123
    }
    constructor(props){
        super(props);
        setInterval(() => {
            this.setState({
                n : this.state.n -1
            })
        },1000);
    }
    render(){
        console.log("A渲染了")
        return(
            <div>
                A组件:{this.state.n}
                <B n={this.state.n}/>
            </div>
        )
    }
}

function B (props){
    return(
        <div>
            B组件:{props.n}
            <C n={props.n}/>
        </div>
    )
}

function C (props){
    return(
        <div>
            C组件:{props.n}
        </div>
    )
}

事件

在react中,组件的事件,本质上就是一个属性,遵循react规范,使用小驼峰命名

内置组件的事件绑定:

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

function a(){
    console.log("点击了")
}
const btn = <button onClick={a} onMouseEnter = {() => {
    console.log("移入了")
}}>点击</button>

ReactDOM.render(btn, document.getElementById('root'));

看下面这个小dome:

index.js中

import React from 'react';
import ReactDOM from 'react-dom';
import Tndexbb from "./Tndexbb";

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

Tndexaa中

import React, { Component } from 'react'

export default class Tndexaa extends Component {
    constructor(props){
        super(props);
        this.state = {
            number : props.number
        }
        const timer = setInterval(() => {
            this.setState({
                number : this.state.number -1
            })
            if(this.state.number === 0){
                clearInterval(timer);
                this.props.abc && this.props.abc()
            }
        },1000)
    }



    render() {
        return (
            <div>
                {/* 要用就必须落实到内置的react元素上面 */}
                <h1 onClick = {this.props.onClick}>
                    倒计时:{this.state.number}
                </h1>
            </div>
        )
    }
}


Tndexaa中

import React, { Component } from 'react'
import Tndexaa from './Tndexaa';
export default class Tndexbb extends Component {

    state = {
        isOVer : false  //倒计时是否完成
    }
    render() {
        let status = "正在倒计时";
        if(this.state.isOVer){
            status = "倒计时完成"
        }
        return (
            <div>
                <Tndexaa number = {5} abc={() => {
                    this.setState({
                        isOVer : true
                    })
                }}
                //onclick只是一个属性,最终还要转化成react元素,要想使用,必须放在对应的内置react元素上面
                onClick = {()=>{
                    console.log("点击了")
                }}/>
                
                <h2>{status}</h2>
            </div>
        )
    }
}

运行效果如下:
在这里插入图片描述
在这里插入图片描述
点击后:
在这里插入图片描述
解决this的指向问题

bind

bind的第一种写法
    constructor(props){
        super(props);
        this.handleClick = this.handleClick.bind(this)
        this.handleOver = this.handleOver.bind(this)
    }
render() {
        let status = "正在倒计时";
        if(this.state.isOVer){
            status = "倒计时完成"
        }
        return (
            <div>
                <Tndexaa 
                    number = {5}
                    // onClick = {this.handleClick}
                    // onOver = {this.handleOver}
                    // bind的第二种写法,第一种复杂,但效率高一些;第二种简单,但效率低,没次都进行了重新的绑定
                    onClick = {this.handleClick.bind(this)}
                    onOver = {this.handleOver.bind(this)}
                    />
                <h2>{status}</h2>
            </div>
        )
    }

箭头函数

 state = {
        isOVer : false 
    }
   //箭头函数的写法  js   next语法
    handleClick = () => {
        console.log(this)
        console.log("点击了")
    }
    handleOver = () => {
        this.setState({
            isOver : true
        })
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值