react组件 组件属性

组件和组件属性

组件:包含内容、样式和功能的UI单元

创建一个组件

特别注意:组件的名称首字母必须大写

用域区分组件还是单个普通的react元素不再是函数ttype

  1. 函数组件

返回一个React元素

分析 首先分为当页js 或者组件js  特别的组件js也要引入react 因为要建立react 元素

其次 渲染函数接受时候两种方式    函数执行状态     组件标签状态   如下

组件返回值仍是一个react元素   变化的只是type值 

function MyCom1() {
    return <li>我的组件1</li>
}
console.log(api.MyCom)
let MyCom = api.MyCom;

    ReactDOM.render(<div>
        <MyCom></MyCom>
        <MyCom1></MyCom1>
    </div>, conter);


//组件内容
import React from 'react';
import ReactDOM from 'react-dom';
let api = {};
 api.MyCom = function() {
     // eslint-disable-next-line react/react-in-jsx-scope
     return <div>我的组件</div>
 }

 // eslint-disable-next-line no-unused-expressions
 export default api;
  1. 类组件

必须继承React.Component

必须提供render函数,用于渲染组件   入口文件每次使用组件都会创建一个react 元素  type为类类型

//组件内容
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
export default class MyClassCom extends Component {
    render() {
        return (
            <div>
               <li>这是类组件元素</li> 
            </div>
        )
    }
}
//入口文件渲染
import MyClassCom from'./MyClassCom'

    ReactDOM.render(<div>
        <MyCom></MyCom>
        <MyClassCom></MyClassCom>
    </div>, conter);

组件的属性

自定义组件传值可以利用属性传html结构代码  映射到react中 是一个对象 

也可以和html一样直接写

传递元素内容

内置组件:div、h1、p

<div>
asdfafasfafasdfasdf
</div>

props.children

props.content1 ......  可以同时将属性和自定义元素传递进去props里面

如果给自定义组件传递元素内容,则React会将元素内容作为children属性传递过去。 会忽略空白

  1. 对于函数组件,属性会作为一个对象的属性,传递给函数的参数
    import React from 'react'
    
    export default function student(props) {
        console.log(props);
        return (
            <div>
                <li>
                    【姓名】:{props.name}
                    【性别】:{props.sex === 0 ? '男' : '女'}
                    【Email】:{props.email}
                    【地址】:{props.address}
                    
                </li>
            </div>
        )
    }
    

     

  2. 对于类组件,属性会作为一个对象的属性,传递给构造函数的参数
  3. 
    import React, { Component } from 'react'
    import Student from './Student'
    
    export default class StudentLIst extends Component {
        render() {
            console.log( this.props.data)
            // eslint-disable-next-line array-callback-return
            var list = this.props.data.map(item => {
                // eslint-disable-next-line no-unused-expressions
                return <Student {...item}></Student>
            })
            console.log(list)
            return (
                <ul>
                    {list}
                </ul>
            )
        }
    }
    

     

注意:组件的属性,应该使用小驼峰命名法

组件无法改变自身的属性

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

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

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

--------------------------------------------------------------------------------------------------------------------------

组件状态

组件状态:组件可以自行维护的数据

组件状态仅在类组件中有效

状态(state),本质上是类组件的一个属性,是一个对象  可以有我们自己控制 供自己使用

状态初始化

初始化要用构造函数初始化


 //初始化组件状态
    constructor(props) {
        super(props);
        console.log(props)
        this.state = {
            left:this.props.left || 0,
            top:this.props.top || 0,
            xSpeed:this.props.xSpeed || 0,
            ySpeed:this.props.ySpeed || 0,
            bg:props.bg || "#f40"
        }
}
 //    必须要用该函数改变state中的数据 才会触发重新渲染
            this.setState({
                left:newLeft,
                top:newTop
            })
        // console.log(this.state)

状态的变化

不能直接改变状态:因为React无法监控到状态发生了变化  会导致其他引用该数据的地方出错

必须使用this.setState({})改变状态

一旦调用了this.setState,会导致当前组件重新渲染  自动触发重新渲染

组件中的数据

  1. props:该数据是由组件的使用者传递的数据,所有权不属于组件自身,因此组件无法改变该数组
  2. 传来的数据不可以改变
  3. state:该数组是由组件自身创建的,所有权属于组件自身,因此组件有权改变该数据 但是改变自己组件的数据依然会影响自己组件的子组件

-----------------------------------------------------------------------------------------

深入认识setState

setState,它对状态的改变,可能是异步的

注意  该setStatus()方法来讲 状态以改变完成之后立马调用render函数 所以render先于数字打印执行 针对回调函数而言

如果改变状态的代码处于某个HTML元素的事件中,则其是异步的,否则是同步

import React, { Component } from 'react'

export default class Test extends Component {
    state = {
        n : 1
    }
    handleChange = () => {
        //改变组件属性 虽然写了多个语句但效果还是一部效果
        // 不可以实现状态的连续改便
        //此处我们想要做到同步改变 但是该方法是异步执行在第二个状态改变时 第一个状态改变尚未完成 故相当于只进行了一次状态改变 
        this.setState({
           n:this.state.n + 1
        })
        this.setState({
            n:this.state.n + 1
         })
         this.setState({
            n:this.state.n + 1
         })
        
        console.log(this.state.n)
        //此时获取到的是状态改变之前的值 0 获取状态改变后的值要用回调函数形式进行
        //但是回调函数仍然无法做到连续改变  需要用回调中嵌套回调才可以
    

    }
    render() {
        console.log('render')
        return (
            <div>
                <span>{this.state.n}</span>
                <button onClick={this.handleChange}>+</button>
            </div>
        )
    }
}

 

 

如果遇到某个事件中,需要同步调用多次,需要使用函数的方式得到最新状态  代码如下

import React, { Component } from 'react'

export default class Test extends Component {
    state = {
        n : 1
    }
    handleChange = () => {
        //改变组件属性 虽然写了多个语句但效果还是一部效果
        // 不可以实现状态的连续改变
        // 改用一下回调函数形式就可实现同步操作 它本质上是异步的
        this.setState({
           n:this.state.n + 1
        },() =>{
            // 注意:
            // 1、该函数在状态改变完成之后调用  该回调函数运行于render之后
            // 今后凡是获取改变后的状态均要使用回调函数形式进行
            console.log(this.state.n)
        })
    }
    render() {
        console.log('render')
        return (
            <div>
                <span>{this.state.n}</span>
                <button onClick={this.handleChange}>+</button>
            </div>
        )
    }
}

最佳实践:

  1. 把所有的setState当作是异步
  2. 永远不要信任setState调用之后的状态  因为它是异步的有可能状态还没有改变
  3. 如果要使用改变之后的状态,需要使用回调函数(setState的第二个参数)
  4. 如果新的状态要根据之前的状态进行运算,使用函数的方式改变状态(setState的第一个函数)

React会对异步的setState进行优化,将多次setState进行合并(将多次状态改变完成后,再统一对state进行改变,然后触发render)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值