React入门系列(五)props和state

props和state都用于描述组件特性,但是,两者有本质区别。前者是由父组件定义的属性变量,后者是组件本身持有的变量。并且,props一旦被定义,就不会再更改;但是,state会随着交互变化而变化。

下面,逐一分析。

1. props

props是properties的缩写,顾名思义,就是属性变量。props用于在父子组件之间传递信息,这种传递是单向的,从父组件到子组件。props一旦被定义,就不可以再修改。

2.state

state是组件维护自身状态的变量,当state更改时,组件会尝试重新渲染。这也充分说明了React数据和模板是单向绑定,数据变化驱动模板更新。

更新state值需要调用组件接口setState

3. 实例

与交互无关的数据一般都定义在props中并渲染出来,对于用户输入,服务器请求或者其他交互变化的响应,需要用state来维护。

下面是一个简单的例子(在Input里面输入任意字符,点击button,会将输入的文字显示在Input框下部,用<li>标签显示)。

react demo 1.png
class Dashboard extends React.Component {
    constructor(props) {
        super(props);
        // 初始化state值
        this.state = {data: [], newItem: ""};
        // 事件函数需要指定调用对象
        this.updateNewItem = this.updateNewItem.bind(this);
        this.addItem = this.addItem.bind(this);
    }

    // 更新state.newItem的值
    updateNewItem(event) {
        this.setState({newItem: event.target.value});
    }

    // 更新state.newItem和state.data的值
    addItem(event) {
        this.state.data.push(this.state.newItem);
        this.setState({newItem: ""});
    }

    render() {
        return (<div className="dashboard">
            <input type="text" value={this.state.newItem} onChange={this.updateNewItem}/>
            <button onClick={this.addItem}>{this.props.text}</button>

            <ItemList data={this.state.data}/>
        </div>);
    }
}

class ItemList extends React.Component {
    render() {
        var listData = this.props.data.map((item, index) => {
            return (<Item text={item} name="item" color="blue" key={index}/>);
        });
        return (<ul>{listData}</ul>);
    }
}

class Item extends React.Component {
    // 根据父组件传递的属性值props渲染子组件
    render(){
        return (<li name={this.props.name} className={this.props.color}>{this.props.text}</li>);
    }
}

ReactDOM.render(
    <Dashboard text="Add!"/>,
    document.getElementById('container')
);

4. props.children

props.children可以访问到组件的子组件集合。如果只有一个子组件,那么返回该子组件对象;如果有多个子组件,则返回包含所有子组件的集合对象。

React提供了帮助函数React.Children.XXX来操作props.children集合对象,帮助函数有:mapforEachcount等。

下面是一个创建按钮组件的例子,利用React.Children.map遍历子组件并给子组件添加统一的属性值。

react demo 2.png
<style>
    .blue {  color: blue;  }
</style>

class ButtonGroup extends React.Component {
    constructor(props) {
        super(props);
    }

    renderChildren() {
        // 利用React.Children.map遍历所有子组件<ButtonOption>对象
        return React.Children.map(this.props.children, (child) => {
            // 复制子组件,并且给全部子组件添加新属性{color: "blue"}
            return React.cloneElement(child, {
                color: "blue"
            })
        });
    }

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

class ButtonOption extends React.Component {
    render() {
        return (<button className={this.props.color} value={this.props.value}>{this.props.text}</button>);
    }
}

ReactDOM.render(
    <ButtonGroup>
        <ButtonOption text="left" value="0"></ButtonOption>
        <ButtonOption text="center" value="1"></ButtonOption>
        <ButtonOption text="right" value="2"></ButtonOption>
    </ButtonGroup>,
    document.getElementById('container')
);

下一节:React入门系列(六)组件间通信

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容