react項目


一、React項目

1、項目依賴安裝

腳手架:

解壓兩個文件:在項目的根目錄下執行npm install////npm I  會按照package.json的配置安裝依賴模塊。

 

安裝完成后,會出現一個node_modules,里面是安裝的所有依賴的模塊。

都是項目的根目錄。

npm install

 

代理是哪里進去哪里出來。

 

2、項目整體說明

.babelrc: babel轉譯的配置文件。 (放的是預設值)環境信息,插件等。

.gitignore(忽略的信息)

Index.html(網頁的HTML顯示信息,發布的站點根目錄)

Jsconfig.json(vscode自己所用的)

LICENSE()

.npmrc()  鏡像庫

Package.js(依賴信息)

README.md()

Src(js的插件信息)

  App.js

  Appstate.js

  Index.html

Node_moudles(npm包管理器設置以后所有的依賴文件)

Webpack.config.dev.js  開發時候使用的

Webpack.config.prod.js  生產環境使用的

 

3、配置文件詳解

1)package.json

Npm 產生的文件,里面記錄項目信息,所有項目依賴。

(1)版本信息:repository:

里面包括的是版本等信息。

 

(2)項目管理:scripts:

 

Start:啟動webpack的dev server開發用的web server,提供的靜態文件加載、自動刷新和熱替換HMR(hot module replacement)

 

HMR可以在應用程序運行中替換,添加和刪除模塊,不需要重新加載模塊,只是變化部分替換掉,不用HMR則自動刷新頁面。

 

--HOT 啟動HMR

--inline默認模式,使用HMR的時候建議使用inline模式,熱替換時候會有消息顯示在控制台。

 

Build使用webpack構建打包,對應npm run build

(3)項目依賴devdependencies

開發時候的依賴,不會打包到目標文件中。例如轉譯代碼等。沒必要到生產中去。

 

Dependencies運行的時候的依賴必須帶到項目中去,

 

 

版本號:

指定安裝版本號:

~安裝指定中和最新的版本。

^安裝指定中最高的版本,不低於指定的版本。*******建議常用

Latest:最新版本。

 

Babel轉譯的。

 

Css樣式:

Css-loader樣式表相關的模塊。

 

React-hot-loader熱加載插件。

 

運行時候的依賴:

 

 

 

 

Antd ant design基於react實現,后台管理較方便。

Axios 異步請求

Polyfiill解決瀏覽器api不支持的問題,磨平差異化。

React開發的主框架。

React-router路由

React-router-dom dom綁定路由

 

Mobx狀態管理庫,透明化

Mobx-react  mobx-react-devtools mobx和react結合的模塊。

React和mobx是一個強強聯合。

2)babel配置,.babelrc

Babel轉譯的配置文件

 

 

3)webpack配置

(1)webpack.config.dev.js

符合commonjs的模塊。

Devtools:’source-map’

調試時候映射處理。

Entry入口:從入口直接找到需要打包的文件。

Output輸出:

Resolve解析

Module模塊

 

 

Test匹配條件的。

Exclude排除的,

Use使用模塊的useentries列表中的loader,

Rules中.js結尾的但不在node_modules目錄的文件使用轉譯babel-loader和熱加載loader。

 

加載器:

style-loader通過<style>標簽吧css添加到dom中。

Css-loader加載css

Less-loader對less的支持

 

Less:控制h2標記的。

 

 

 

 

Devserver,開發使用的server

 

Compress啟動gzip

Port啟動端口3000

Hot啟動HMR

Proxy執行訪問/api開頭路徑都代理到http://127.0.0.0:8080

4)vscode的配置

Jsconfig.json是vscode的配置文件,覆蓋當前配置。

 

上面的配置文件,需要更改name,version,description,需要修改repository倉庫地址,需要修改author、license信息。修改完成后,進行開發。

 

 

 

 

App-xxxxx的文檔必須放在根目錄,對於Windows下的是磁盤的根目錄。

 

4、啟動項目

npm start

 

 

二、react

1、簡介

React是Facebook開發的並開源的前端框架。

2013年開源的,react解決的是前端的MVC框架中的view視圖層的問題。

2、virtual dom***

DOM是什么?

DOM(文檔對象模型document object model)

是HTML和xml文檔,把其解析成為dom對象,展示成為樹的模型。

Js在瀏覽器端多數情況下都是操作dom樹的。

 

 

選擇節點問題,通過id等進行查找等。

 

The document

 

 

The dom tree

 

 

將網頁所有內容映射到一顆樹形的結構的層級對象模型上,瀏覽器提供對dom支持,用戶可以用腳本調用dom api來動態的修改dom節點,從而達到修改網頁的目的,這種修改在瀏覽器中完成,瀏覽器胡根據dom的修改重繪dom的節點部分。

 

修改dom重新渲染的代價比較高,前端框架為了提高效率,盡量減少DOM的重繪,提出了virtual DOM,所有的修改都是現在的virtual dom上面完成,通過比較算法,找出瀏覽器和dom之間的差異,使用這個差異操作dom,瀏覽器只是需要渲染這個部分變化就行了。

 

React實現了dom diff算法可以高效比對vir dom和 dom的差異。

 

 

3、jsx的語法。

Jsx是一種Javascript和xml混寫的語法,是Javascript的擴展。

直接插入HTML語句等。

 

 

4、測試程序

import React from 'react';

import ReactDOM from 'react-dom';

// import { render } from 'react-dom';

// import { AppContainer } from 'react-hot-loader';

// import AppState from './AppState';

// import App from './App';

 

// const appState = new AppState();

 

// render(

//   <AppContainer>

//     <App appState={appState} />

//   </AppContainer>,

//   document.getElementById('root')

// );

 

// if (module.hot) {

//   module.hot.accept('./App', () => { render(App) })

// }

 

class Root extends React.Component{

  render(){

    return <div>javascript excise</div>;

  }

}

 

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

 

Return的必須是jsx的語法。單標計必須是封口的。

Render()渲染函數,必須有return值,必須有頂級元素返回,所有元素必須閉合。

單行省略小括號,多好使用小括號。

 

class Root extends React.Component{

  render(){

    return <div>javascript <br/> excise</div>;

  }

}

 

 

<br/>換行符

 

 

 

 

 

 

 

 

class Root extends React.Component{

  render(){

    return React.createElement('div',null,'javascript');

    //return <div>javascript <br/> excise</div>;

  }

}

 

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

ReactDom.render(React.createElement(Root),document.getElementById('root'));

 

 

 

更改屬性的值:大括號等信息。

 

 

增加一個子元素:

class SubEle extends React.Component{

  render(){

    return <div>Sub content</div>

  }

}

 

class Root extends React.Component{

  render(){

    return (

      <div>

        <h2>welcome to study</h2>

        <br/>

        <SubEle/>

      </div>);

  }

}

 

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

 

 

 

React組件的render函數return,只能是一個頂級元素。

Jsx語法是XML,要求所有元素必須閉合,<br/>  不能是<br>

 

5、jsx規范

標簽中首字母小寫就是HTML標記,首字母大寫就是組件。

要求嚴格的標記,要求所有標簽必須閉合,br也應該寫成<br  />,/前面留一個空格。

單行省略小括號,多行必須使用小括號。

元素有嵌套的,多行,縮進。

Jsx表達式:使用{}括起來,如果大括號內使用了引號,會當做字符串處理。

 

6、組件狀態state

每一個react組件都有一個狀態變量state,是一個JavaScript對象,為期定義屬性保存值。

狀態變化了,會出發UI重新渲染,使用setstate方法重新修改state的值。

State是組件內部使用的,是私有屬性。

import React from 'react';

import ReactDOM from 'react-dom';

 

class Root extends React.Component{

  state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    this.state.p1 = 'www.abc'

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

      </div>

    );

  }

 

}

 

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

 

//this.state.p1 = 'www.abc'

改為下面的,不允許,不允許對更新中的state進行setState

    //this.setState({p1:'www.ab'})  //不允許這樣修改,控制台會報錯,

使用延時函數:setTimeout(里面是一個函數)   

setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

 

 

class Root extends React.Component{

  state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允許這樣修改,控制台會報錯,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

      </div>

    );s

  }

 

}

 

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

 

 

7、復雜例子

 

Div的id是t1,鼠標按下事件就捆綁了一個函數,只要鼠標按下就會觸發調用getEventTrigger函數,瀏覽器就會給其送一個參數event,event是時間對象,當時間觸發的時候,event包含觸發這個時間的對象。

8、HTML DOM的Javascript事件

屬性

此事件發生在何時

Onabort

圖像的加載被中斷

Onblur

元素失去焦點

Onchange

域的內容被改變

Onclick

當用戶點擊某個對象時候調用的時間句柄

Ondbclick

當用戶雙擊某個對象時候調用的事件句柄

Onerror

在加載文檔或圖像時候發生錯誤

Onfocus

元素獲得焦點

Onkeydown

某個鍵盤鍵被按下

Onkeypress

某個鍵盤按鍵被按下並松開

Onkeyup

某個按鍵被松開

Onload

一張頁面或一幅圖像完成加載

Onmousedown

鼠標按鈕被按下

Onmousemove

鼠標按鍵被移動

Onmouseout

鼠標從某元素移開

Onmouseover

鼠標移到某個元素之上

Onmouseup

鼠標按鍵被松開

Onreset

重置按鈕被點擊

Onresize

窗口或框架被重新調整大小

Onselect

文本被選中

Onsubmit

確認按鈕被點擊

Onunload

用戶退出頁面

 

import React from 'react';

import ReactDOM from 'react-dom';

class Toggle extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    點擊這句話,會觸發一個事件1。{this.state.flag.toString()}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允許這樣修改,控制台會報錯,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle />

      </div>

    );

  }

}

 

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

 

 

 

 

Toggle類

有自己的state屬性,當render完成后,網頁上有一個div標簽捆綁了一個click事件的函數,div標簽內有文本內容。

如果用過點擊左鍵,就觸發了click方法關聯的handleClick函數,在這個函數里將狀態值改變。

 

狀態值state的改變將引發render重繪。

{this.handleClick.bind(this)},不能外加引號。

This.handleClick.bind(this)一定要綁定this,否則當觸發捆綁的函數時候,this是函數執行的上下文決定的,this已經不是觸發事件的對象了。

Console.log(event.target.id)取回的產生事件的對象的id,不是封裝的組件的對象,所以,console.log(event.target===this)是false,這個this是通過綁定過來的。

 

React的事件:

使用小駝峰命名。

使用jsx表達式,表達式中要指定事件處理函數。

不能使用return false,如果要阻止事件默認行為,使用event.preventDefault()

 

Id是唯一的,堅決不能有重復的。

 

9、props

 

把react組件當做標簽使用,可以為其增加屬性:

 

組件之間利用state或者傳parent傳遞參數

修改屬性是不可以的,因為是只讀的this.props.name.

 

import React from 'react';

import ReactDOM from 'react-dom';

 

class Toggle extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    點擊這句話,會觸發一個事件1。{this.state.flag.toString()}

    {this.props.school}{this.props.age}

    <br />

    {this.props.parent.state.p1}

    {this.props.children}

    </div>;

  }

}

 

class Toggle1 extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t2" onClick={this.handleClick.bind(this)}>

    點擊這句話,會觸發一個事件2。{this.state.flag.toString()}

    <br />

    {this.props.name}

    <hr />

    {this.props.age}

    {this.props.parent.state.p2}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允許這樣修改,控制台會報錯,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle school='abc' age= '20' parent={this} >

        </Toggle>

        <Toggle1 name='tom' age= '10' parent={this}/>

      </div>

    );

  }

}

 

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

注意訪問parent送進去的是this,訪問實例本身的屬性的方式是利用this.props.state.p1的值

 

 

 

10、構造器

利用construc(props)。

Super()調用父類的。

只要extends的,必須利用super()調用。Props作為參數傳入。

import React from 'react';

import ReactDOM from 'react-dom';

 

class Toggle extends React.Component{

  constructor(props){

    console.log('Toggle')

    super(props)

    this.state = {flag:true};

  }

 

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    點擊這句話,會觸發一個事件1。{this.state.flag.toString()}

    {this.props.school}{this.props.age}

    <br />

    {this.props.parent.state.p1}

    {this.props.children}

    </div>;

  }

}

 

class Toggle1 extends React.Component{

  constructor(props){

    console.log('Toggle1')

    super(props)

    this.state = {flag:true};

  }

 

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t2" onClick={this.handleClick.bind(this)}>

    點擊這句話,會觸發一個事件2。{this.state.flag.toString()}

    <br />

    {this.props.name}

    <hr />

    {this.props.age}

    {this.props.parent.state.p2}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允許這樣修改,控制台會報錯,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle school='abc' age= '20' parent={this} >

        </Toggle>

        <Toggle1 name='tom' age= '10' parent={this}/>

      </div>

    );

  }

}

 

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

 

 

 

 

11、組件的生命周期

組件的聲明周期可分為三個狀態。

Mounting:已插入真實dom。

Updating:正在被重新渲染。

Unmounting:已移除真實dom。

 

方法如下:

(1)裝載組件觸發:

Componentwillmount在渲染前調用,在客戶端也在服務器端,指揮在裝載前調用一次。

Componentdidmount:在第一次渲染后調用,只要是在客戶端,之后的組件已經生成對應的dom結構,可以通過this.getdomnode()來進行訪問, 想與其他的Javascript框架一起使用,在這個方法中調用setTimeout,setinterval或者發送ajax請求等操作,只是在裝載完后調用一次,在render之后。

(2)更新組件觸發,這些方法不會再首次render組件的周期調用。

Componentwillreceiveprops(nextprops)在組件接受到一個新的prop時候被調用,在初始化render時候不會調用。

Shouldcomponentupdae(nextprops,nextstate)返回布爾值,在組件接受到新的Props或者state時候被調用,在初始化或者使用forceupdate時候不被調用。(如果設置為false,就不允許更新組件。)

Componentwillupdate(nextprops,nextstate)在組件接受到新的props或者state還沒render時候被調用,在初始化不會調用。

Componentdidupdate(prevprops,prevstate)在組件完成后更新后立即調用,在初始化時候不會被調用。

(3)卸載組件觸發

ComponentwillUNmount在組件從dom中移除的時候立即被調用

 

 

圖中,constructor構造器是最早執行的函數,觸發更新生命周期的函數,需要更新state或者props。

 

import React from 'react';

import ReactDOM from 'react-dom';

 

class Sub extends React.Component{

  constructor(props){

    console.log('sub con')

    super(props)

    this.state = {count:0}

  }

  handleClick(event){

    this.setState({count:this.state.count + 1});

  }

  render(){

    console.log('sub render')

    return <div id='sub'onClick={this.handleClick.bind(this)}>

    Sub's count = {this.state.count}

    </ div>

  }  

  componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

}

 

class Root extends React.Component{

  constructor(props){

    console.log('root con')

    super(props)

    this.state = {}

  }

  render(){

    return <div>

        <Sub  />

        </ div>

  }

}

 

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

 

 

 

順序是constructor  =》 componentwillmount =》 render =》 componentdidmount –state或props改變,render。

 

import React from 'react';

import ReactDOM from 'react-dom';

import { ENGINE_METHOD_DIGESTS } from 'constants';

 

class Sub extends React.Component{

  constructor(props){

    console.log('sub con')

    super(props)

    this.state = {count:0}

  }

  handleClick(event){

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

  }

  render(){

    console.log('sub render')

    return <div id='sub'onClick={this.handleClick.bind(this)}>

    Sub's count = {this.state.count}

    <a style={{height:200+'px',color:'red',backgroundColor:'#f0f0f0'}} >

    </ a>

 

    </ div>

  }  

  componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

  componentWillReceiveProps(nextProps){

    //props變更時候,接受新的props,交給shouldComponentUpdate

    //props組件內只讀,只能從外部改變

 

    console.log(this.props)

    console.log(nextProps)

    console.log('sub componentWillReceiveProps',this.state.count);

  }

 

  shouldComponentUpdate(nextProps,nextState){

    //是否組件更新,props或state方式改變時候,返回布爾值,true才會更新

    console.log('sub shouldComponentUpdate',this.state.count,nextState)

    return true

  }

  componentWillUpdate(nextProps,nextState){

    //同意更新后,真正更新之前,調用render

    console.log('sub componentWillUpdate',this.state.count,nextState)

  }

  componentDidUpdate(prevProps,prevState){

    //同意更新后,真正更新后,在render之后調用。

    console.log('sub componentDidUpdate',this.state.count,prevState)

  }

}

 

class Root extends React.Component{

  constructor(props){

    console.log('root con')

    super(props)

    this.state = {}

  }

  render(){

    return <div>

        <Sub  />

        </ div>

  }

}

 

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

 

 

 

Componentwillmount第一次裝載,在首次render之前,例如控制state、props。

Componentdidmount第一次裝載結束,在首次render之后,控制state,props。

Componentwillreceiveprops在組件內部,props是只讀不可變的,這個函數接受到新的props,可以對props做一些處理,this.props={name:‘root’}這就是偷梁換柱,componentwillreceiveprops觸發,也會走shouldcomponentupdate。

Shouldcomponentupdate判斷是否需要組件更新,是否render,精確的控制渲染,提高性能。

Componentwillupdate除了首次render之外,每次render前執行,componentdidupdate在render之后調用。

 

componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

  componentWillReceiveProps(nextProps){

    //props變更時候,接受新的props,交給shouldComponentUpdate

    //props組件內只讀,只能從外部改變

 

    console.log(this.props)

    console.log(nextProps)

    console.log('sub componentWillReceiveProps',this.state.count);

  }

 

  shouldComponentUpdate(nextProps,nextState){

    //是否組件更新,props或state方式改變時候,返回布爾值,true才會更新

    console.log('sub shouldComponentUpdate',this.state.count,nextState)

    return true

  }

  componentWillUpdate(nextProps,nextState){

    //同意更新后,真正更新之前,調用render

    console.log('sub componentWillUpdate',this.state.count,nextState)

  }

  componentDidUpdate(prevProps,prevState){

    //同意更新后,真正更新后,在render之后調用。

    console.log('sub componentDidUpdate',this.state.count,prevState)

  }

}

 

 

 

12、無狀態組件

也叫做函數式組件。

許多時候組件簡單不需要state狀態,也不需要聲明周期函數,無條件組件很好的滿足了需要,無狀態組件提供了一個參數props,返回一個react元素,無狀態組件函數本身就是render函數。

 

import React from 'react';

import ReactDOM from 'react-dom';

 

//let Root = props =><div>{props.shoolname}</div>;

 

//ReactDOM.render(<Root shoolname='abc' />,document.getElementById('root'))

 

function Root(props){

  return <div> {props.name}</div>

}

 

ReactDOM.render(<Root name='bcd'/>,document.getElementById('root'))

 

 

 

 

三、高階組件

 

1、柯里化

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = function (Component){

  function _wrapper(props){

    return (

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

  }

  return _wrapper

}

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = function (Component){

  return props=>(

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

}

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Component=> props =>(

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

2、裝飾器

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Component=>props=>

 

  (<div>

    {props.aname}

    <hr />

    <Component />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper

class Root extends React.Component{

  render(){

    return <div> Root</ div>

  }

}

 

let Newarpper = wrapper(Root)

 

ReactDOM.render(<Newarpper aname='abc' />,document.getElementById('root'))

 

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Components=>props=>

 

  (<div>

    {props.aname}

    <hr />

    <Components {...props} />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper

class Root extends React.Component{

  render(){

    return <div> Root{this.props.aname}</ div>

  }

}

 

 //let Newarpper = wrapper(Root)

 

ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))

 

 

Root中也顯示props.name的屬性,使用  <Components {...props} />

增加屬性等。

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = id => Components=>props=>

 

  (<div id = {id}>

    {props.aname}

    <hr />

    <Components {...props} />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper('wrapper')

class Root extends React.Component{

  render(){

    return <div> Root{this.props.aname}</ div>

  }

}

 

 //let Newarpper = wrapper(Root)

 

ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))

 

 

 

 

 

 

 

 

 

函數后面不能加括號調用,因為加括號返回的不是組件,而是render函數需要的內容。

要求返回的是組件,組件函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM