1. 程式人生 > >react-入門

react-入門

.com length targe default CA 創建 只需要 console 適合

基礎認識

  • 官網
  • 特點
  • 聲明式編程
  • 組件化
  • 支持客戶端和服務端渲染
  • 高效
    • 虛擬DOM,不總是直接操作DOM,只是減少DOM的操作,操作虛擬DOM不會對頁面進行重繪,當渲染的時候,才會進行渲染
    • DOM Diff 算法,最小化頁面重繪,就是當頁面變化時,通過計算那部分需要重繪,只重繪當前部分,減少頁面的重繪區域
  • 單向數據流
  • js文件
  • react.js:react的核心庫
  • react-dom.js:提供操作DOM的react擴展
  • babel.js:解析jsx語法
    <div id="app"></div>
    <script src="js/react.development
.js"></script> <script src="js/react-dom.development.js"></script> <script src="js/babel.min.js"></script> <script type="text/babel"> // 創建虛擬DOM元素對象 let vDom = <h1>react hello</h1> // 將虛擬DOM渲染到頁面真實DOM容器中 ReactDOM.render
(vDom,document.getElementById(‘app‘)) </script>

JSX

  • react提供了創建虛擬DOM的方法
  • 虛擬DOM對象最終都會被react轉換為真實的DOM
  • 編碼時,只需要操作react的虛擬DOM相關數據,react會轉換為真實DOM變化而更新界面
// react直接操作和JSX操作對比
<script type="text/javascript">
    const msg = ‘MSG content‘
const msgId = ‘App‘

// 創建虛擬DOM
// const VDom1 = React.createElement(‘標簽名‘,{id:‘xxx‘},‘內容‘)
const vDom1 = React.createElement(‘h1‘, { id: msgId.toLowerCase() }, msg.toLowerCase()) // 渲染虛擬DOM ReactDOM.render(vDom1, document.getElementById(‘app1‘)) </script> <script type="text/babel"> // 創建虛擬DOM const vDom2 = <h2 id={msgId.toUpperCase()}>{msg.toLowerCase()}</h2>; // 渲染虛擬DOM ReactDOM.render(vDom2, document.getElementById(‘app2‘)) </script>
  • 動態渲染一個列表
  • 使用數組的Map函數返回所需要的列表內容
let arrs = [111,222,333,444]
// 創建虛擬DOM 
const ul = (
    <ul>
    {
        arrs.map((name,index) => <li key={index}>{name}</li>)
    }
    </ul>
)

// 渲染虛擬DOM 
ReactDOM.render(ul, document.getElementById(‘app1‘))

組件

  • 工廠函數創建組件
  • 使用工廠函數的效率比使用class高,因為工廠函數中不需要創建一系列的對象之類的
  • 當組件有狀態(state)的時候就不適合使用了
// 工廠函數創建組件
function MyCom(){
    return <h2>工廠函數創建組件</h2>            
}
        
// 渲染組件標簽
// <MyCom />必須這麽寫
// <MyCom>這麽寫是錯誤的
ReactDOM.render(<MyCom />,document.getElementById(‘app‘))
  • class創建組件
// class定義組件
class MyCom2 extends React.Component{
    render(){
        return <h3>class定義組件</h3>
    }
}

// 渲染組件標簽
// <MyCom2 />必須這麽寫
// <MyCom2>這麽寫是錯誤的
ReactDOM.render(<MyCom2 />,document.getElementById(‘app‘))

組件三大屬性

state

  • state是組件對象的最重要的屬性之一,值是一個對象,這個對象可以包含多個數據
  • 組件被稱為狀態機,通過更新組件的state來更新對應的頁面顯示,就是通過state來控制組件的重新渲染(重繪)

  • 初始化狀態

constructor(props){
    super(props)
    this.state = {
        stateProp1:value1,
        stateProp2:value2
    }
}
  • 讀取某個狀態值
this.state.statePropertyName
  • 更新狀態:組件重新渲染
this.setState({
    stateProp1:newValue1,
    stateProp2:newValue2
})
  • 案例:點擊切換內容
//定義組件
class Like extends React.Component{
    constructor(props){
        super(props)
        //初始化狀態state
        this.state = {
            isShow:false
        }
        
        //將新增方法中的this強制綁定為組件對象
        this.handleClick = this.handleClick.bind(this)
    }
    
    // 新添加的方法:內置的this默認不是組件對象,是一個undefined
    handleClick(){
        //獲取原始狀態並取反
        let isShow = !this.state.isShow
        // 設置狀態
        this.setState({isShow})
    }
    
    // React.Component中本身就具有render函數,在class中只是重寫組件類的方法render,所以這裏的this指向沒有問題
    render(){
        //獲取狀態
        // const isShow = this.state.isShow
        const {isShow} = this.state
        //onClick是react的,區分原生的onclick
        // this.handleClick.bind(this)也可以,但是這種效率比較低,因為每次render都會執行一次bind進行綁定,而在constructor中只會在初始化的時候綁定一次
        return <h1 onClick={this.handleClick}>{isShow ? ‘我是帥哥‘ : ‘帥哥是我‘}</h1>
    }
    
}

//渲染組件
ReactDOM.render(<Like/>,document.getElementById(‘app‘))

props

  • 案例:定義一個顯示個人信息的組件
  • 姓名必須指定
  • 性別默認為男
  • 年齡默認為18
//創建組件
/* function Person(props) {
    return (
        <ul>
            <li>姓名:{props.name}</li>
            <li>性別:{props.sex}</li>
            <li>年齡:{props.age}</li>
        </ul>
    )
} */

// class創建
class Person extends React.Component{
    render(){
        return (
            <ul>
            <li>姓名:{this.props.name}</li>
            <li>性別:{this.props.sex}</li>
            <li>年齡:{this.props.age}</li>
            </ul>
        )
    }
}
        
//屬性默認值
Person.defaultProps = {
    sex:‘man‘,
    age:18
}

//屬性的類型和必填
Person.propTypes = {
    name:PropTypes.string.isRequired,
    age:PropTypes.number
}

const p1 = {
    name:‘nordon‘,
    sex:‘man‘,
    age:22
}
// 渲染組件
// ReactDOM.render(<Person name={p1.name} sex={p1.sex} age={p1.age} />,document.getElementById(‘app‘))
ReactDOM.render(<Person {...p1} />,document.getElementById(‘app‘))

const p2 = {
    name:‘lisan‘
}   
ReactDOM.render(<Person name={p2.name}  age={19}/>,document.getElementById(‘app2‘))

refs與事件處理

  • 案例:獲取input中的值
//定義組件
class MyInput extends React.Component {
            
    constructor(props){
        super(props)
        this.handleClick = this.handleClick.bind(this)
        this.handleBlur = this.handleBlur.bind(this)
    }

    handleClick(){
        let input1 = this.refs.inputValue
        console.log(input1.value)
        console.log(this.newInput.value)
    }

    handleBlur(event){
        console.log(event.target.value)
    }

    render (){
        return (
            <div>
                <input type="text" ref="inputValue" />&nbsp;&nbsp;
                <input type="text" ref={inputValue => this.newInput = inputValue } />&nbsp;&nbsp;
                <button onClick={this.handleClick}>獲取值</button>&nbsp;&nbsp;
                <input type="text" placeholder="失去焦點獲取值" onBlur={this.handleBlur} />
            </div>
        )
    }
}
        
//渲染組件
ReactDOM.render(<MyInput/>,document.getElementById(‘app‘))

ToDolist

  • 簡單的tdolist案例
// 定義組件
// 組件狀態的更改必須在當前組件中進行
class App extends React.Component{ 

    constructor(props){
        super(props)

        this.state = {
            todos:[‘111‘,‘222‘,‘333‘]
        }

        this.addTodo = this.addTodo.bind(this)
    }

    addTodo(todo){
        let {todos} = this.state
        todos.unshift(todo)
        this.setState({
            todos
        })
    }

    render(){ 
        const {todos} = this.state
        return (
            <div>
            <h1>this is todolist demo</h1>
            <Add count={todos.length} addTodo={this.addTodo} />
            <List todos={todos} />
            </div>
        ) 
    }
}

class Add extends React.Component{ 
    constructor(props){
        super(props)

        this.handleAdd = this.handleAdd.bind(this)
    }
    handleAdd(){
        // console.log(this.refs.content.value);
        // <input  type="text" ref="content" /> &nbsp;&nbsp;
        // console.log(this.newTodos.value);
        const data = this.newTodos.value
        if(!data){
            return false;
        }
        this.newTodos.value = ‘‘
        this.props.addTodo(data)
    }
    render(){
        return (
            <div>
            <input  type="text" ref={inputValue => this.newTodos = inputValue} /> &nbsp;&nbsp;
            <button onClick={this.handleAdd}>按鈕#{this.props.count + 1}</button>
            </div>
        )
    }
}
Add.propTypes = {
    count:PropTypes.number.isRequired,
    addTodo:PropTypes.func.isRequired
}

class List extends React.Component{

    render(){
        let {todos} = this.props
        return (
            <div>
            <ul>
            {todos.map( (item,index) => <li key={index}>{item}</li> )}
            </ul>
            </div>
        )
    }
}
// name:PropTypes.string.isRequired,
List.propTypes = {
    todos:PropTypes.array.isRequired
}

// 渲染組件
ReactDOM.render(<App/>,document.getElementById(‘app‘))

react-入門