react数据流

本文深入探讨React中State与Props的概念与应用,解析组件间数据流动机制,阐述两者如何影响组件渲染及通信,强调其在React开发中的核心地位。

在React中,数据是自顶向下流动的,即从父组件到子组件。这条原则让组件之间的关系变得简单且可预测。

state与props是React组件中最重要的概念。如果顶层组件初始化props,那么React会向下遍历整棵组件树,重新渲染相关的子组件。而state只关心每个组件自己内部的状态,这些状态只能在组件内改变。把组件看成一个函数,那么它接受了props作为参数,内部由state作为函数的内部参数,返回Virtual DOM的实现。

1.state

state是用来管理组件自身内部状态的。

当组件内部使用库内置的setState方法时,最大的表现行为就是该组件会尝试重新渲染。这很好理解,因为我们改变了内部状态,组件需要更新了。比如,我们实现了一个计数器组件:

import React,{ Component } from 'React';

class Counter 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>
        );    
    }
}

a标签中监听点击事件,点击则执行handleClick,实现了点击一次计数加一。state中的count就是我们需要操作的数据

 

2.props

props是React中另一个重要的概念,它是properties的缩写。props是React用来让组件之间相互联系的一种机制,通俗地说就像方法的参数一样。

props本身是不可变的。当我们试图改变props的原始值时,React会报出类型错误的警告。

以tabs组件为例,之前tab的数据都是通过data prop传入的,即<Tabs data ={data} />

props还会有以下几项

className:根节点的class

classPrefix:  class前缀,定义一个统一的class前缀,对样式和交互分离起到了非常重要的作用

defaultActive和activeIndex:默认的激活索引

onchange: 回调函数

React追求直观,所以在定义内容区域只显示子组件的集合,而把具体的功能留给子组件去实现

<Tabs classPrefix={'tabs'} defaultActiveIndex={0}>
    <tabPane key={0} tab={'Tab 1'}> 1 </tabPane>
    <tabPane key={1} tab={'Tab 2'}> 2 </tabPane>
    <tabPane key={2} tab={'Tab 3'}> 3 </tabPane>
</Tabs>

 只有key和tab两个props放在了Tabs组件上,而其他参数直接放在TabPane组件中,由它的父组件TabContent隐式对TabPane组件拼接

1.子组件prop

在React中有一个重要且内置的prop ————children,它代表组件的子组件集合。children可以根据传入子组件的数量来决定是否是数组类型。

getTabPanes() {
     const { classPrefix, activeIndex, panels, isActive } = this.props;
    return React.Children.map(panels, (child) => {  //map遍历子组件
    if(!child){ return ;}
    const order = parseInt(child.props.order, 10);  //把子组件的索引转换成数字
    const isActive = activeIndex === order;    //isActive找到激活的组件索引
    return React.cloneElement(child, {  //用React的cloneElement方法克隆到TabPane组件中
        classPrefix,
        isActive,
        children: child.props.children,
        key: 'tabpane-${order}',
    });
});   
}

通过React.Children.map遍历子组件,最后渲染组件的时候直接在render函数中调用 getTabPanes方法。

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

2.组件props

<TabPane order="0" tab={<span><i className="fa fa-home"></i>&nbsp;Home</span>}>

 tab传入了一个节点,这就是component props

3.用function prop与父组件通信

对于props来说,它的通信是父组件向子组件的传播。

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

回调函数给父组件必要的值

4.propTypes

propTypes用于规范props的类型与必须的状态。如果组件定义了propTypes,那么在开发环境下,就会对组件的props值类型作检查,如果传入的props不能与之匹配,React将在控制台报warning.

static propTypes = {
    classPrefix: React.PropTypes.string.isRequired
};

对于prop classPrefix规定必须为string类型,如果是必须的,可以在最后加上isRequired

propTypes有很多类型支持,不仅有基本类型,还包括枚举和自定义类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值