1. 程式人生 > >我們一起踩過的坑----react(antd)

我們一起踩過的坑----react(antd)

1.this問題對應寫法

1)

this.handleChange = this.handleChange.bind(this) //如果不寫這個,必須要用箭頭函式

 

handleChange(e) {

this.setState({temperature: e.target.value});

2)

handleChange=(e)=> {

this.setState({temperature: e.target.value});

}

 

2.react沒有直接的獲取大量表單資料的方法,只能一個一個獲取,這時候要藉助一些第三方的外掛,比如antd裡面的

 

if(item.inputType==="daterange"){

const TIMEPICKER= <FormItem label={label} key={field}>

{getFieldDecorator(field)(

<RangePicker locale={locale} style={{width:225}}/>

)}

</FormItem>

formItemList.push(TIMEPICKER)

}

 

最後一鍵獲取表單資料

 

let fieldsValue=this.props.form.getFieldsValue();

 

3.react的state的非同步問題:在React庫控制之內時,它就會以非同步的方式來執行,否則以同步的方式執行。

也就是你setState的同時,輸入設定的state的往往無法同步

state本身的設計是無法直接更改,setState的設計是用來更動state

 

4.資料存放問題 

當你純渲染一個元件的時候,你可以接受父級傳過來的資料,this.props.data直接使用 

在判斷哪一個是 state 時,簡單地對每一項資料提出三個問題: 
1.是否是從父級通過 props 傳入的?如果是,可能不是 state 。 
2.是否會隨著時間改變?如果不是,可能不是 state 。 

3.能根據元件中其它 state 資料或者 props 計算出來嗎?如果是,就不是 state 。

 

5.tabs頁切換,導航選單跟著聯動 

在tabs的onChange函式中呼叫子元件NavLeft裡的方法,將activeKey傳過去,在從openKey的鍵值對中遍歷,找到相應的openKeys值,將openKeys傳到state中即可。

這時候,請注意,設定過 onOpenChange的裡面必須要setState({openKeys}),否則點選選單無法開啟;其次,openKeys是一個數組,而並不是字串

 

6.動態新增一行表格,裡面又是一些表單input問題 

製作這個功能的時候,我肯定首選UI的表單方法:

 

<FormItem>

{getFieldDecorator('remember', {

valuePropName: 'checked',

initialValue: true

})(

<Checkbox>記住密碼</Checkbox>

)}

<span>忘記密碼</span>

<Button style={{width:'100%'}} type="primary" onClick={this.handleSubmit}>登入</Button>

</FormItem>

 

但是完成之後發現,新增後的表單無法鍵入,目前還不知道什麼原因

所以只能捨棄官網的方法,用迴圈將input塞進去

獲取資料的方法是,只要使用者鍵入資料,將資料暫存在本地,點提交,再將資料融合,一起提交,暫時還沒想到其他方法

 

7.tabs的路由問題 

其實當初是想做那種點選NavLeft的選單,新增路由,自動增加tabs

但是呢,對於剛接觸react的新人來說,不知從何下手,看了很多部落格,也無法獲知有用的方法

所以,迫於無奈,最終的方案是 點選選單,獲取id值,手動新增tabs的panes,然後在根據panes裡面的title匹配相應的模板元件,是之載入資料,並沒有用到路由的相關技術,

希望以後能改寫這段程式碼···

 

 8.content頁下滑,tabs置頂問題

<Col span="20" className="main" onScroll={this.handleScroll}>

將要滾動判斷的部分繫結handScroll函式 

handleScroll=(e)=>{        

        let scrollTop = e.target.scrollTop; //滾動條滾動高度

        let scrollHeight = e.target.scrollHeight

        let obj =document.getElementsByClassName("ant-tabs-bar")[0]

        if(scrollTop>50 && scrollHeight>705){

            obj.style.position = 'fixed';

            obj.style.top = '0';    

            obj.style.background='#002140'  

            obj.style.width='100%'      

        }else{

            obj.style.position = 'static';

        }

    }

 

9.使用SuperAgent傳輸資料

 附上乾糧:https://www.jianshu.com/p/98b854322260

封裝 SuperAgent方法,供後續使用,附上程式碼

export default class Superagent{

static super(options){

return new Promise((resolve,reject)=>{

superagent

.post(options.url)

.type('form')

.set("datamobile-token",tokenName)

.query(options.query||'')

.send(options.data||'')

.end((req,res)=>{

if(res.status===200){

resolve(res.body)

}else if(res.status===200){

message.info("請求許可權不足,可能是token已經超時")

}else if(res.status===404||res.status===504){

message.info("頁面不存在。")

}else if(res.status===500){

message.info("後臺處理錯誤。")

}else{

reject(res.body)

}

})

})

}

}

 

10. RightBar導航錨點實現

{

this.state.cardTitle?

this.state.cardTitle.map((item)=>{

return <li onClick={()=>this.scrollToAnchor(item)} key={item}>{item}</li>

}):""

}

將導航綁點scrollToAnchor方法,之所以不用a標籤的錨點功能呢,原因有2:一是使用a標籤,href中帶#號的,react會預設去實現路由跳轉;二是要去增加一些Id,比較麻煩

scrollToAnchor = (anchorName) => {

if (anchorName) {

let anchorElement = document.getElementById(anchorName);

if(anchorElement) { anchorElement.scrollIntoView({behavior: 'smooth'})}

}

}

scrollIntoView方法是H5新增方法,具體引數詳見傳送門:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView

 

 11.antd的Select,Cascader,Datepicker的下拉框隨著頁面的滾動而滾動

這個問題是官方預設相對於頁面body定位,只要改為相對於父級定位就可以了 

 Select,Cascader使用

getPopupContainer={trigger => trigger.parentNode}

 Datepicker使用

getCalendarContainer={trigger => trigger.parentNode}

 

12.antd upload限制檔案型別和數量 

const props = {

accept:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.ms-excel",

onChange : () => {

fileList.slice(-1);//限制一個檔案數量

},

onRemove : (file) => {

this.setState((state) => {

const index = state.fileList.indexOf(file);

const newFileList = state.fileList.slice();

newFileList.splice(index, 1);

return {

fileList: newFileList,

begin:true,

percent:0,

};

});

},

beforeUpload: (file) => {

this.setState(state => ({

fileList: [file],

begin:false

}));

return false;

},

fileList,

};

常用檔案型別:

字尾名 MIME名稱

*.3gpp audio/3gpp, video/3gpp

*.ac3 audio/ac3

*.asf allpication/vnd.ms-asf

*.au audio/basic

*.css text/css

*.csv text/csv

*.doc application/msword

*.dot application/msword

*.dtd application/xml-dtd

*.dwg image/vnd.dwg

*.dxf image/vnd.dxf

*.gif image/gif

*.htm text/html

*.html text/html

*.jp2 image/jp2

*.jpe image/jpeg

*.jpeg image/jpeg

*.jpg image/jpeg

*.js text/javascript, application/javascript

*.json application/json

*.mp2 audio/mpeg, video/mpeg

*.mp3 audio/mpeg

*.mp4 audio/mp4, video/mp4

*.mpeg video/mpeg

*.mpg video/mpeg

*.mpp application/vnd.ms-project

*.ogg application/ogg, audio/ogg

*.pdf application/pdf

*.png image/png

*.pot application/vnd.ms-powerpoint

*.pps application/vnd.ms-powerpoint

*.ppt application/vnd.ms-powerpoint

*.rtf application/rtf, text/rtf

*.svf image/vnd.svf

*.tif image/tiff

*.tiff image/tiff

*.txt text/plain

*.wdb application/vnd.ms-works

*.wps application/vnd.ms-works

*.xhtml application/xhtml+xml

*.xlc application/vnd.ms-excel

*.xlm application/vnd.ms-excel

*.xls application/vnd.ms-excel

*.xlt application/vnd.ms-excel

*.xlw application/vnd.ms-excel

*.xml text/xml, application/xml

*.zip aplication/zip

*.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet