react - 1. 定义组件和组件的属性

使用用法:

  • 如何定义组件
  1. 函数式组件(就是一个函数,接收一个属性对象,返回一个react元素)

函数式组件渲染:
1 - 封装函数组件的属性对象 props = {name: ‘haha’}
2 - 把props传递给welcome1函数,返回一个React元素
3 - 把这个React元素,也就是虚拟DOM渲染到真实DOM

  1. 类组件(就是一个类,需要一个render函数,render返回返回并仅能返回一个顶级react元素)

类组件渲染:
1 - 封装函数组件的属性对象 props = {name: ‘haha’}
2 - new Welcome2(props) 创建 Welcome2 这个类的实例,传递 props 进去
3 - 调用实例的 render 方法,返回 React 元素
4 - 把这个React元素,也就是虚拟DOM渲染到真实DOM

import React from 'react';
import ReactDOM from 'react-dom';
// 函数式组件
function Welcome1 (props) {
    return <h1>{props.name}</h1>
}
// 类组件
class Welcome2 extends React.Component {
    render() {
        return <h1>{this.props.name}</h1>
    }
}
let element = <div>
    <Welcome1 name="haha" />
    <Welcome2 name="hehe" />
</div>
ReactDOM.render(element, document.getElementById('root'))
  • props

props 具有只读性
代码如上

  • PropType 类型校验
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from "prop-types"

class Welcome extends React.Component {
    // 默认参数值
    static defaultProps = {
        name: '默认名称'
    }
    // 参数校验
    static propTypes = {
        name: PropTypes.string.isRequired, // 字符串类型的必传字段
        // 自定义校验器,props 属性对象 ; propName属性名称 ; componentName 组件名称
        age(props, propName, componentName) {
            let age = props[propName]
            if(age < 0 || age > 120) throw new Error('年龄应该在0 - 120')
        }
    }
    render() {
        return <h1>{this.props.name}</h1>
    }
}
let props = {
    name: '张阿三',
    age: 10
}
let element = <Welcome { ...props } />
ReactDOM.render(element, document.getElementById('root'))

源码实现:

  1. react.js
class Component {
    static isReactComponent = true
    constructor(props) {
        this.props = props
    }
}
function createElement(type, config = {}, ...children) {
    let props = {
        ...config,
        children
    }
    return {
        type, props
    }
}
export default {
    createElement,
    Component
}
  1. react-dom.js
function render(element, container) {
    if(typeof element === 'string' || typeof element === 'number') {
        return container.appendChild(document.createTextNode(element))
    }
    let type, props;
    type = element.type
    props = element.props
    let isReactComponent = type.isReactComponent
    if(isReactComponent) {
        // 类组件
        let componentInstance = new type(props)
        element = componentInstance.render()
        type = element.type
        props = element.props
    } else if(typeof type === 'function') {
        // 函数式组件
        element = type(props)
        type = element.type
        props = element.props
    }
    let dom = createDOM(type, props)
    container.appendChild(dom)
}
function createDOM(type, props) {
    let dom = document.createElement(type)
    for(let propName in props) {
        if(propName === 'children') {
            props.children.forEach(child => render(child, dom))
        } else if(propName === 'className') {
            dom.className = props[propName]
        } else if(propName === 'style') {
            let styleObj = props[propName]
            for(let attr in styleObj) {
                dom.style[attr] = styleObj[attr]
            }
        }else {
            dom.setAttribute(propName, props[propName])
        }
    }
    return dom
}
export default {
    render
}
  1. 调用
import React from "./yuanma/react"
import ReactDOM from "./yuanma/react-dom"
// 函数组件
function Welcome(props) {
    return React.createElement('h1', {
        className: 'title',
        id: "test",
        style: {
            color: 'red'
        }
    }, 'hello1', React.createElement('span', null, 'world1'))
}
// 类组件
class Welcome extends React.Component {
    render() {
        return React.createElement('h1', {
            className: 'title',
            id: "test",
            style: {
                color: 'red'
            }
        }, 'hello1', React.createElement('span', null, 'world12'))
    }
}
let element = React.createElement(Welcome, {})
ReactDOM.render(element, document.getElementById('root'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值