React筆記:組件(3)

1. 組件定義

  組件是React的核心概念,組件將應用的UI拆分紅獨立的、可複用的模塊。css

  定義組件的兩種方式:react

  (1)類組件:使用ES6 class數組

  (2)函數組件:使用函數瀏覽器

  使用class定義組件的兩個條件:dom

  (1)class繼承自React.Component函數

  (2)class內部必須定義render(),render()返回表明該組件UI的React元素。ui

1.1 基本組件

  HelloWorld.js:this

import React, { Component } from "react"

class HelloWorld extends Component {
    render() {
        return ( 
            <h1>Hello World!</h1>
        );
    }
}

export default HelloWorld;

  Index.js:spa

import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld />, document.getElementById('root'));

  說明:ReactDOM.render()須要先導入react-dom庫,這個庫會完成組件所表明的虛擬DOM節點到瀏覽器的DOM節點的轉換。設計

     使用export default默認導出組件。

     default表示能夠在別的文件中使用import HelloWorld from './components/HelloWorld'導入這個模塊;

     若是沒有default,則須要使用import { HelloWorld } from './components/HelloWorld'來導入模塊。

1.2 組件的props

  組件props用於把父組件中的數據或方法傳遞給子組件。

  props是一個簡單結構的對象,它包含的屬性是由組件做爲JSX標籤所使用的屬性組成。

  示例(1):

import React, { Component } from "react"

class HelloWorld extends Component {
    render() {
        return ( 
            <h1>Hello { this.props.name }!</h1>
        );
    }
}

export default HelloWorld;
import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld name={ 'Libing' } />, document.getElementById('root'));

  示例(2):

  TodoItem.js

import React, { Component } from 'react';

class TodoItem extends React.Component {
    render() {
        const { id, title } = this.props;
        
        return (
            <li>{ id }-{ title }</li>
        );
    }
}

export default TodoItem;

  TodoList.js

import React, { Component } from 'react';

import TodoItem from './TodoItem';

const data = [
    { id: 1, title: 'ToDo' },
    { id: 2, title: 'In Progress' },
    { id: 3, title: 'Done' }
]

class TodoList extends Component {
    render() {
        return ( 
            <ul>
            {
                data.map((item) =>
                    <TodoItem
                        id={ item.id }
                        title={ item.title }
                    />
                )
            } 
            </ul>
        );
    }
}

export default TodoList;

  index.js

import React from 'react';
import ReactDOM from 'react-dom';

import TodoList from './components/TodoList'

ReactDOM.render(<TodoList />, document.getElementById('root'));

1.3 組件的state

  組件的state是組件內部的姿態,state的變化最終將反映在組件UI的變化。

  在組件的構造方法constructor中經過this.state定義組件的初始狀態,並經過調用this.setState()改變組件狀態,進而組件UI會隨之從新渲染。

  修改TodoItem.js

import React, { Component } from 'react';

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

        this.state = {
            count: 0
        };
    }

    handleClick() {
        let count = this.state.count;
        count++;

        this.setState({
            count: count
        });
    }

    render() {
        const { id, title } = this.props;

        return (
            <li>
                { id }-{ title }-{ this.state.count }
                <button
                    onClick={() => {
                        this.handleClick();
                    }}
                >+1</button>
            </li>
        );
    }
}

export default TodoItem;

1.4 有狀態組件和無狀態組件

  state用來反映組件內部狀態的變化。

  無狀態組件:若是一個組件的內部狀態是不變的,則用不到state。

  有狀態組件:若是一個組件的內部狀態會發生變化,就須要使用state來保存變化。

  示例:

  HelloWorld.js

import React from 'react';

function HelloWorld(props) {
    return <h1>Hello { props.name }!</h1>;
}

export default HelloWorld;

  注:因爲使用了JSX,須要導入React。

  index.js

import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld name={ 'World' } />, document.getElementById('root'));

  在使用無狀態組件時,儘可能定義函數組件。

  在開發React應用時,要先思考哪些組件應該設計成有狀態組件,哪些組件應該設計成無狀態組件。而且,儘量多的使用無狀態組件,無狀態組件不用關心狀態變化,只聚焦於UI的展現,更容易複用。

  React應用組件設計的通常思路:經過定義少數的有狀態組件管理整個應用的狀態變化,而且將狀態經過props傳遞給其他的無狀態組件,由無狀態組件完成頁面絕大部分UI的渲染。

  有狀態組件主要關注處理狀態變化的業務邏輯,無狀態組件主要關注組件的UI渲染。

1.5 屬性校驗和默認屬性

1.5.1 屬性校驗

  React提供PropTypes用於校驗組件屬性的類型。

import React from 'react';
import PropTypes from 'prop-types'

class HelloWorld extends React.Component {
    render(){
        return (<h1>Hello { this.props.name }!</h1>);
    }
}

HelloWorld.propTypes = {
    name: PropTypes.string
}

export default HelloWorld;
import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld name={'World'} />, document.getElementById('root'));

  若屬性類型設置number,則報錯提示。

import React from 'react';
import PropTypes from 'prop-types'

class HelloWorld extends React.Component {
    render(){
        return (<h1>Hello { this.props.name }!</h1>);
    }
}

HelloWorld.propTypes = {
    name: PropTypes.number
}

export default HelloWorld;

import React from 'react';
import PropTypes from 'prop-types'

class HelloWorld extends React.Component {
    render(){
        return (<h1 style={ this.props.style }>Hello { this.props.name }!</h1>);
    }
}

HelloWorld.propTypes = {
    name: PropTypes.string,
    style: PropTypes.shape ({
        color: PropTypes.string,
        fontSize: PropTypes.number
    }).isRequired
}

export default HelloWorld;
import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld
    style={{ color: 'red', fontSize: 14 }}
    name={'World'}
/>, document.getElementById('root'));

  示例中,style是一個對象,包含兩個屬性color和fontSize,color是字符串類型,fontSize是數字類型。

  若是屬性是組件的必須屬性,在PropTypes的類型屬性上調用isRequired。

1.5.2 默認屬性

  React提供爲組件屬性指定默認值,組件defaultProps。當組件屬性未被賦值時,組件會使用defaultProps定義的默認屬性。

import React from 'react';

class HelloWorld extends React.Component {
    render(){
        return (<h1 style={ this.props.style }>Hello { this.props.name }!</h1>);
    }
}

HelloWorld.defaultProps = {
    name: 'Libing'
}

export default HelloWorld;
import React from 'react';
import ReactDOM from 'react-dom';

import HelloWorld from './components/HelloWorld'

ReactDOM.render(<HelloWorld />, document.getElementById('root'));

1.6 組件樣式

  爲組件添加樣式的方法主要有兩種:外部樣式表和內聯樣式。

1.6.1 外部CSS樣式表

  樣式表引入的兩種方式:

  (1)在使用組件的HTML頁面中經過標籤引入

<link rel="stylesheet" type="text/css" href="style.css" >

  (2)把樣式表看成一個模塊,在使用該樣式表的組件中,導入樣式表文件

import './style.css'; // 相對路徑

  React元素要使用className代替class做爲選擇器。

  /src/components/HelloWorld.css

.hello-world {
    color: red;
    font-size: 14px;
}

  /src/components/HelloWorld.js

import React from 'react';

import './HelloWorld.css';

class HelloWorld extends React.Component {
    render(){
        return (<h1 className='hello-world'>Hello World!</h1>);
    }
}

export default HelloWorld;

  第一種引入樣式表的方式經常使用於該樣式表做爲整個應用的全部組件(基礎樣式表),第二種引入樣式表的方式經常使用於該樣式表做用於某個組件(組件的私有樣式)。

  全局基礎樣式表要可使用第二種方式引入,通常在應用的入口js文件中引入,如index.js。

1.6.2 內聯樣式

  內聯樣式是一種CSS in JS的寫法:將CSS寫到JS文件中,用JS對象表示CSS,經過DOM類型節點的style屬性引用樣式對象。

import React from 'react';

class HelloWorld extends React.Component {
    render(){
        return (<h1 style={{
            color: 'red',
            fontSize: '14px'
        }}>Hello World!</h1>);
    }
}

export default HelloWorld;

  style使用了兩個大括號{{}},第一個大括號表示style的值是一個JavaScript表達式,第二個大括號表示這個JavaScript表達式是一個對象。

import React from 'react';

class HelloWorld extends React.Component {
    render(){
        const style = {
            color: 'red',
            fontSize: '14px'
        };
    
        return (<h1 style={ style }>Hello World!</h1>);
    }
}

export default HelloWorld;

2. 組件生命週期

相關文章
相關標籤/搜索