React入門系列(五)props和state

props和state都用于描述組件特性,但是,兩者有本質區(qū)別。前者是由父組件定義的屬性變量,后者是組件本身持有的變量。并且,props一旦被定義,就不會再更改;但是,state會隨著交互變化而變化。

下面,逐一分析。

1. props

props是properties的縮寫,顧名思義,就是屬性變量。props用于在父子組件之間傳遞信息,這種傳遞是單向的,從父組件到子組件。props一旦被定義,就不可以再修改。

2.state

state是組件維護自身狀態(tài)的變量,當state更改時,組件會嘗試重新渲染。這也充分說明了React數(shù)據(jù)和模板是單向綁定,數(shù)據(jù)變化驅動模板更新。

更新state值需要調用組件接口setState

3. 實例

與交互無關的數(shù)據(jù)一般都定義在props中并渲染出來,對于用戶輸入,服務器請求或者其他交互變化的響應,需要用state來維護。

下面是一個簡單的例子(在Input里面輸入任意字符,點擊button,會將輸入的文字顯示在Input框下部,用<li>標簽顯示)。

react demo 1.png
class Dashboard extends React.Component {
    constructor(props) {
        super(props);
        // 初始化state值
        this.state = {data: [], newItem: ""};
        // 事件函數(shù)需要指定調用對象
        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 {
    // 根據(jù)父組件傳遞的屬性值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提供了幫助函數(shù)React.Children.XXX來操作props.children集合對象,幫助函數(shù)有:mapforEachcount等。

下面是一個創(chuàng)建按鈕組件的例子,利用React.Children.map遍歷子組件并給子組件添加統(tǒng)一的屬性值。

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')
);

下一節(jié):React入門系列(六)組件間通信

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容