<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [toc] ## 轉換過程:jsx->React.createElement->{虛擬dom} ``` import React from 'react'; //這個名字不能隨便改 因為編譯后就叫這個名字 看77行 import ReactDOM,{render} from 'react-dom'; //jsx語法時facebook自己發明的 babel-preset-react let ele = <h1 className="read"><span>zfpx</span>hello,world</h1>; //以上等同于以下 // type,props,children React.createElement( "h1" //type ,{ className:'read' } ,React.createElement( "span" ,null ,"zfpx" ) ,"hello,world" ); // -> // let obj = { // type:'h1' // ,props:{ // className:'red' // ,children:[ // {type:'span',props:{children:'zfpx'}} // ,'hello,world' // ] // } // } ``` ## prop-types和屬性驗證 ``` import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; let person = { name:'ahhh' ,age:111 ,gender:'男' ,hobby:['sleeping'] ,salary:100 } class Person extends Component{ // Person.propTypes = static propTypes = { name:PropTypes.number.isRequired ,age:PropTypes.number ,gender:PropTypes.oneOf(['男','女']) ,hobby:PropTypes.array ,salary:function(props,keyName,componentName){ if(props[keyName]<1000){ throw new Error(`${componentName}error${props[keyName]}is too low`) //Person error 100 is too low } } ,position:PropTypes.shape({ x:PropTypes.number ,y:PropTypes.number }) } constructor(props){ super(); } render(){ let{name,age,gender,hobby,salary,position} = this.props; return( <div> {this.props.name} </div> ) } } ``` ## React.createElement和ReactDOM.render 原理 ``` class Element{ constructor(type,props){ this.type = type; this.props = props; } } let React = { createElement(type,props,...children){ if(children.length === 1)children = children[0]; return new Element(type,{...props,children}); } }; function render(eleObj,container){ let {type,props} = eleObj; let ele = document.createElement(type); for(let key in props){ if(key!=='children'){ if(key === 'className'){ ele.setAttribute('class',props[key]); }else{ ele.setAttribute(key,props[key]); } } else{ // 是我們的兒子節點 let children = props[key]; if(Array.isArray(children)){ // 是數組 children.forEach(child=>{ if(child instanceof Element){ render(child,ele); }else{ ele.appendChild(document.createTextNode(child)); } }); }else{ if(children instanceof Element){ render(children,ele); }else{ ele.appendChild(document.createTextNode(children)); } } } } container.appendChild(ele); } // render(ele,window,root); ``` ## JSX ``` import React from 'react'; //這個名字不能隨便改 因為抽象語法樹編譯后就是React React.createElement import ReactDOM,{render} from 'react-dom'; //jsx和html寫法不完全一樣 // className ->class // htmlFor -> label的for // jsx元素可以嵌套 //相鄰的react元素 不能不被包裹使用 必須加一層標簽 //jsx里面可以放js 里面區分是不是js根據的是{} let name = '' let ele = ( <React.Fragment> <label htmlFor="a"></label> <input type="text" id='a'/> <h1> {/*注釋*/} {name}{age} {function name(params) {return 100}()} {1+3}{1==1?'2':'3'} </h1> <h1 style={{background:'red'}}>hello</h1> <div dangerouslySetInnerHTML={{__html:'<h1>hello ahhh</h1>'}}></div> {/*相當于innerHtml*/} </React.Fragment> ); render(ele,window.root); ``` ## render第一個參數放函數 ``` //渲染函數 import React from 'react'; import ReactDOM from 'react-dom'; //1) function school(name,age){ return <h1>{name}{age}</h1> } ReactDOM.render(school('ahhh',111), document.getElementById('root')); //2) let el = ( <ul>{school('ahhh',111)}</ul> ) ReactDOM.render(el,window.root) //3) let dinner = ['漢堡','可樂','薯條']; let eleObj = dinner.map((item,index)=>( <li key={index}>{item}</li> )); ReactDOM.render(eleObj,window.root); ``` ## 組件 ``` //組件分兩種 函數組件(函數)function 類組件 class //函數組件中沒有this 沒有聲明周期 沒有狀態 import React from 'react'; import ReactDOM from 'react-dom'; //怎么區分是組件還是jsx元素 //如果名字是大寫就是組件,小寫就是jsx元素 //組件必須要有返回值 也可以返回null null也是合法的 function School(props){ // return null return <h1>{props.name}{props.age}</h1> } //School({name:'ahhh',age:111}); //組件可以通過屬性傳遞數據 ReactDOM.render(<School name='ahhh' age='111'/>, document.getElementById('root')); ``` ## 函數組件和類組件與時鐘示例 ``` import React from 'react'; import ReactDOM from 'react-dom'; function Clock(props){ return ( <div> <span>當前時間:</span> {props.date.toLocaleString()} </div> ) } //不會一直渲染 只渲染一次 ReactDOM.render(<Clock date={new Date()}/>, document.getElementById('root')); //組件的特點 就是復用 多次使用 setInterval(function(){ ReactDOM.render(<Clock date={new Date()}/>, document.getElementById('root')); },1000); ``` ``` import React from 'react'; import ReactDOM from 'react-dom'; class Clock extends React.Component{ constructor(){ super(); this.state = {date:new Date().toLocaleString(),name:'ahhh'} } // state = {date:new Date().toLocaleString()} //如果用類組件需要提供一個render方法 // 組件渲染完成后會調用這個生命周期 componentDidMount(){ setInterval(()=>{ this.setState({date:new Date.toLocaleString()}); },1000); } render(){ return ( <span>時間是:{this.state}</span> ) } } ReactDOM.render(<Clock/>,window.root); //組件有兩個數據源 一個是屬性 外界傳遞的 還有一個叫狀態是自己的 //都會導致頁面刷新 // 你傳遞的屬性可能不是我預期的 ``` ## 組件通信 ![](https://box.kancloud.cn/86d0db46d19ab323795317e46ed96df1_744x111.png) ## 關于React.createElement ![](https://box.kancloud.cn/1928509184762f9f6e89383ad0bc6d92_668x75.png) ``` //編輯后就是 React.createElement //大寫的React ``` ## 父組件會在子組件DidMount后才DidMount(包括父組件重新Mount,子組件也會重新Mount,然后父組件才DidMount) ## 16.3新特性 ### React.createRef() ``` export default class xxx extends React.Component{ constructor(){ super(); this.text = React.createRef(); } componentDidMount(){ // this.text.focus(); this.text.current.focus(); } render(){ return ( <div> {/*<input type="text" ref={(input)=>{this.text=input}}/>*/} {/*會自動的將當前輸入框 放在this.text.current*/} <input type="text" ref={this.text}/> </div> ) } } ``` ### getDerivedStateFromProps ![](https://box.kancloud.cn/209e765566e1c1b426b91f04d6093722_586x366.png) ### getSnapshotBeforeUpdate ![](https://box.kancloud.cn/99fee69979284c8fc86226b3a4cb772b_476x237.png) ![](https://box.kancloud.cn/08bc9a257cc90acfe3726b788c16c014_844x155.png) ## react-redux 如果老的狀態和新的狀態時同一個(地址) ![](https://box.kancloud.cn/221c7aed8422289df2b6931321bc4b59_663x311.png) `react-redux`是不會允許更新視圖的 ![](https://box.kancloud.cn/f99e02d6e8aba9fe74f589c9a1939503_561x288.png) ## immutable.js ``` let {Map} = require('immutable'); // 導入immuatable //1.只操作對象 let obj = {a:1}; //返回的m1 就是不可變對象,永遠不會變 let m1 = Map(obj); ``` set ``` // let m2 = m1.set('a',100); //調用set后永遠返回的都是一個新的不可變對象 ``` update ``` let m2 = m1.update('a',(a)=>a+100); console.log(m1.get('a')); console.log(m2.get('a')); ``` Map 只處理一層 ``` let obj = {a:{a:1},b:2}; let m1 = Map(obj); console.log(m1); ``` 可以發現下面第二層的數據不大對 ![](https://box.kancloud.cn/6188d073bbd4a29c473e5aafd8fe5d5d_456x92.png) 多層使用`fromJS` ![](https://box.kancloud.cn/d7a7bc1f40aa96433df150c5c05dffce_556x213.png) ![](https://box.kancloud.cn/5087b133a8a5e0c3f4dcb07d8dbdfffe_556x206.png) 嵌套多層時 改變深層的屬性 ``` let {Map,fromJS} = require('immutable'); let obj = {a:{b:{c:{d:1},d:100},m:100}}; let m1 = fromJS{obj}; m1.setIn(['a','b','c','d'],2); // ->a.b.c.d = 2 并且返回新對象 ``` getIn ``` console.log(m1.getIn(['a','b','c','d'])); ``` immutable 支持對數組操作 List -> 相當于操作對象時的Map 多層級時仍然使用`fromJS` ``` let m1 = List([[1,2,3],[4,5,6]]) let m1 = fromJS([[1,2,3],[4,5,6]]) ``` `immutable`對象不可直接訪問其屬性 ``` let m1 = fromJS({a:1}); console.log(m1); ``` ![](https://box.kancloud.cn/35705e59f5137c6cbb5f6d229f9f803c_243x88.png) ``` console.log(m1.a) <<< undefined ``` 可以使用`toJS`方法將immutable對象轉換為普通js對象 ![](https://box.kancloud.cn/df02396d7529850c20e7fb9f4764fabd_377x340.png) 兩個`immutable`對象一定是不相同的,但如果我們想要比較兩個對象中的值一不一樣,可以使用`is()`方法 ![](https://box.kancloud.cn/53c06437469862602b7b1d0aad215e78_352x120.png) ### immutable在react中的應用 ![](https://box.kancloud.cn/e7e30186b9295c66a1ee44c8e4b471cc_643x528.png) ### redux-immutable ![](https://box.kancloud.cn/b05954dccfe61182b422db194beec291_545x60.png) 不再用redux里的cmobineReducers ![](https://box.kancloud.cn/d2136d6920c1873a1010e9f07cfddbc8_641x207.png) ![](https://box.kancloud.cn/37e4bf9032d6a73aa3681521fdace493_666x232.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看