react初步学习二

React 组件

传统方法(JavaScript)的规范标准组件信息

  1. 基本的封装性。
  2. 简单的生命周期呈现。
  3. 明确的数据流动。

Web Components 的组成成分

这里写图片描述
1. HTML Templates 定义了之前模板的概念
2. Custom Elements 定义了组件的展现形式
3. Shadow DOM定义了组件的作用域范围、可以囊括样 式
4. HTML Imports 提出了新的引入方式。

React 组件的构建

这里写图片描述

React 组件基本上由组件的构建方式、组件内的属性状态与生命周期方法组成。

React 组件可以接收参数,也可能有自身状态。一旦接收到的参数或自身状态有所改变, React 组件就会执行相应的生命周期方法,最后渲染。

React 与 Web Components 的不同

  1. React 自定义元素是库自己构建的
  2. React 渲染过程包含了模板的概念(JSX)
  3. React 组件的实现均在方法与类中,因此可以做到相互隔离,但不包括样式
  4. React 引用方式遵循 ES6 module 标准

React组件构建的三种官方方式

  • React.createClass( 最传统、也是兼容性最好)
    示例:
const Button = React.createClass({
    getDefaultProps() {
        return {
            color: 'blue',
            text: 'Confirm',
        };
    },
    render() {
        const { color, text } = this.props;
        return ( 
            <button className = {`btn btn-${color}`}>
                <em>{ text }</em>
            </button>
        );
    }
});

构建新的组件对象。
当另一个组件需要调用 Button 组件时,只用写成 <Button />,就可以被解析成 React.createElement(Button) 方法来创建 Button

  • ES6 classes
import React, { Component } from 'react';
class Button extends Component {
    constructor(props) {
        super(props);
    }
    static defaultProps = {
        color: 'blue',
        text: 'Confirm',
    };
    render() {
        const { color, text } = this.props;
        return (
            <button className = {`btn btn-${color}`}>
                <em>{text}</em> 
            </button>
        );
    }
}

从调用内部方法变成了用类来实现

说明:React 的所有组件都继承自顶层类 React.Component。它的定义非常简洁,只是初始化了 React.Component 方法,声明了 props、context、refs 等,并在原型上定义了 setState 和 forceUpdate 方法。内部初始化的生命周期方法与 createClass 方式使用的是同一个方法 创建的。

  • 无状态 函数(stateless function)
function Button({ color = 'blue', text = 'Confirm' }) {
    return (
        <button className={`btn btn-${color}`}>
            <em>{text}</em>
        </button>
    );
}

无状态组件只传入 props 和 context 两个参数;也就是说,它不存在 state,也没有生命周期方法,组件本身即上面两种 React 组件构建方法中的 render 方法。

优点:创建时始终保持了一个实例,避免了不必要的检查和内存分配,做到了内部优化

React数据流

数据是自顶向下单向流动的,从父组件到子组件。

  • state
    自身管理组件的内部状态
    当使用了setState时,组件重新渲染
    注意:setState——异步操作
    :计数器
import React, { Component } from 'react'; 
class Products extends Component {
  constructor(props) {
    super(props); 
    this.handleClick = this.handleClick.bind(this); 
    this.state = {
      count: 0,
    };
  } 
  handleClick(e) {
    e.preventDefault();
    this.setState({
      count: this.state.count + 1,
    });
  } 
  render() {
    return (
      <div>
        <p>{this.state.count}</p>
        <a href="#" onClick={this.handleClick}>更新</a>
      </div>
    );
  }
} 

export default Products;

在这里我们就定义了一个state——count
点击“更新”,数字+1
点击“更新”,数字+1

  • props
    组件之间 互相联系的一种机制,通俗地说就像方法的参数一样
    组件的props一般包含:
    ①. className:根节点的 class
    ②. classPrefix:class 前缀
    ③. defaultActiveIndex 和 activeIndex:默认的激活索引
    ④. onChange:回调函数

    1. 子组件prop
      1) 通过React.Children.map 方法遍历子组件
      2) React.cloneElement( element, [props], [...children] )方法克隆到子组件中
      3) 最后返回
      这种子组件的返回方式叫做动态子组件

getTabPanes() {
    const { classPrefix, activeIndex, panels, isActive } = this.props;
    return React.Children.map(panels, (child) => {
        if (!child) { return; }
        const order = parseInt(child.props.order, 10);
        const isActive = activeIndex === order;
        return React.cloneElement(child, {
            classPrefix,
            isActive,
            children: child.props.children,
            key: `tabpane-${order}`,
        });
    });
}

调用方法:

render() {
    return (<div>{this.getTabPanes()}</div>);
} 

                     2. 组件props
                       1)对于子组件而言,我们不仅可以直接使用 this.props. children 定义,也可以将子组件以 props 的形式传递
                       2)可以加入更多的自定义元素,可以是多行的,甚至可以插入动态数据。

getTabs() {
    const { classPrefix, activeIndex, panels } = this.props;
    return React.Children.map(panels, (child) => {
        if (!child) { return; }
        const order = parseInt(child.props.order, 10);
        let classes = classnames({
            [`${classPrefix}-tab`]: true,
            [`${classPrefix}-active`]: activeIndex === order,
            [`${classPrefix}-disabled`]: child.props.disabled,
        });
        return (<li>{child.props.tab}</li>);
    });
}

                     3. function prop 与父组件通信
                       1) 对于 state 来说,通信集中在组件内部
                       2) 对于 props 来说,通信是父组 件向子组件的传播
相关代码:

handleTabClick(activeIndex) {  
    // ... 
    this.props.onChange({ activeIndex, prevIndex });
}

点击事件 handleTabClick 触发了 onChange prop 回调函数给父组件必要的值

                     4. propTypes
                       propTypes 用于规范 props 的类型与必需的状态。
                       1) 如果组件定义了propTypes,那么在开发环 境下,就会对组件的 props 值的类型作检查
                     2)如果传入的 props 不能与之匹配,React 将实时在控 制台里报 warning
                       3) 在生产环境下,这是不会进行检查的

Tabs 组件的 propTypes

static propTypes = {
    classPrefix: React.PropTypes.string,
    className: React.PropTypes.string,
    defaultActiveIndex: React.PropTypes.number,
    activeIndex: React.PropTypes.number,
    onChange: React.PropTypes.func,
    children: React.PropTypes.oneOfType([
        React.PropTypes.arrayOf(React.PropTypes.node),
        React.PropTypes.node,]),
};

TabPane 组件 的 propTypes

static propTypes = {
    tab: React.PropTypes.oneOfType([
        React.PropTypes.string, React.PropTypes.node,
    ]).isRequired,
    order: React.PropTypes.string.isRequired,
    disable: React.PropTypes.bool,
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值