blog/React開發(fā)中提升幸福度的一些小技巧.md

第一道菜:回鍋肉

react數(shù)組循環(huán)瞭吃,基本都會設(shè)置一個唯一的key马篮,表格的對象數(shù)組循環(huán)一般沒什么問題晤柄,數(shù)據(jù)基本都會有一個id粟判。那有種情況就比較坑了亿昏,出現(xiàn)在表單形式的頁面結(jié)構(gòu)中,對某個數(shù)組進(jìn)行增刪改操作档礁,一般對于非對象數(shù)組而言角钩,沒有id,可能很多人會偷懶呻澜,循環(huán)的時候递礼,直接設(shè)置數(shù)組的下標(biāo)index作為key,當(dāng)出現(xiàn)增刪改時候羹幸,就會出現(xiàn)數(shù)據(jù)對不上或者重新渲染組件的問題等脊髓。解決方案有很多種,例如把字符串?dāng)?shù)組等重組對象數(shù)組睹欲,每個元素設(shè)置一個唯一id等供炼。另外有個方式:推薦使用shortid生成唯一key的數(shù)組,和數(shù)據(jù)數(shù)組一起使用窘疮,省去提交數(shù)據(jù)時再重組數(shù)組袋哼。

importReactfrom'react';importshortidfrom'shortid';classDemoextendsReact.Component{constructor(props) {super(props);this.state={data:['a','b','c']}this.dataKeys=this.state.data.map(v=>shortid.generate());}deleteOne=index=>{//刪除操作const{data}=this.state;this.setState({ data:data.filter((v,i)=>i!==index) });this.dataKyes.splice(index,1);? ? }render() {return(<ul>{data.map((v,i)=><li? ? ? ? ? ? ? ? ? ? ? ? onClick={i=>this.deleteOne(i)}? ? ? ? ? ? ? ? ? ? ? ? ? key={this.dataKeys[i]}>{v}</li>)? ? ? ? ? ? ? }</ul>)}}//稍微抽取,可以封裝一個通用的組件

第二道菜:番茄炒蛋

通過判斷值是否存在來控制元素是否顯示闸衫,一般三目運(yùn)算可以達(dá)到此效果涛贯,最簡單的還是用短路的寫法:

//不錯constflag='something';flag&&<div></div>//很好//注意一般可能上面寫法多一些,但當(dāng)flag為0 的時頁面上會顯示0蔚出,用!!將其轉(zhuǎn)為boolean避免坑弟翘,//代碼也更規(guī)范constflag='something';!!flag&&<div></div>

第三道菜:酸辣土豆絲

使用組件,傳遞props:

const{data,type,something}=this.state;<Demo? ? data={data}? ? type={type}? ? something={something}/>

也許另外一種傳遞方式更簡潔:

const { data, type, something } = this.state;

<Demo

? ? {...{ data, id, something }}

/>

第四道菜:清炒時蔬

組件的props有時候會定義很多骄酗,但是調(diào)用組件傳遞props的時候又想一個個傳稀余,不想一次性傳遞一個option對象,通過擴(kuò)展運(yùn)算符和解構(gòu)賦值可以簡化此操作:

const Demo = ({ prop1, prop2, prop3, ...restProps }) => (

? ? <div>

? ? ? ? xxxx

? ? ? ? { restProps.something }

? ? </div>

)

// 父組件使用Demo

<Demo

? ? prop1={xxx}

? ? prop2={xxx}

? ? something={xxx}

/>

第五道菜:小吃-糍粑

一般改變state值的一種方式:

const{data}=this.state;this.setState({ data:{...data, key:1} });

另外一種可以通過callback的方式改變state的值

this.setState(({ data })=>({ data:{...data, key:1} }));

還可以:

this.setState((state,props)=>{return{ counter:state.counter+props.step};});

第六道菜:水煮肉片

React 性能優(yōu)化有很多種方式趋翻,那常見的一種就是在生命周期函數(shù)shouldComponentUpdate里面判斷某些值或?qū)傩詠砜刂平M件是否重新再次渲染睛琳。

判斷一般的字符串,數(shù)字或者基礎(chǔ)的對象踏烙,數(shù)組都還是比較好處理师骗,那嵌套的對象或者數(shù)組就比較麻煩了,對于這種讨惩,可以轉(zhuǎn)成字符串處理辟癌,但屬性值的位置不同時,那就無效了荐捻。

推薦使用lodash(或者其他的類似庫)的isEqual對嵌套數(shù)組或?qū)ο筮M(jìn)行判斷(相比其他方式更簡單些)

shouldComponentUpdate(nextProps,nextState) {if(_.isEqual(nextState.columns,this.state.columns))returnfalse;returntrue;}

第七道菜:干鍋兔

創(chuàng)建彈層的三種方式:

普通組件通過state和樣式控制黍少,在當(dāng)前組件中顯示彈層-每次引入組件并且render里面控制顯示寡夹,掛載節(jié)點(diǎn)在某組件里面

//彈層constDialog=()=><div>彈層</div>//某組件render() {return(this.state.showDialog&&<Dialog/>)}

2.通過Portals創(chuàng)建通道,在根節(jié)點(diǎn)外部掛載組件-但還是需要每次引入并且在render里面調(diào)用

//彈層classDialogextendsReact.Component{constructor(props) {super(props);this.el=document.createElement('div');? }componentDidMount() {modalRoot.appendChild(this.el);? }componentWillUnmount() {modalRoot.removeChild(this.el);? }render() {returnReactDOM.createPortal(this.props.children||<div>xxxx</div>,this.el,? ? );? }}//某組件render() {return(this.state.showDialog&&<Dialog/>)}

3.推薦使用ReactDom.render創(chuàng)建彈層-掛載根節(jié)點(diǎn)外層仍侥,使用也更方便

//demoletdialog;classDialog{show(children) {//顯示this.div=document.createElement('div');document.body.appendChild(this.div);ReactDom.render(children||<div>xxxx</div>,this.div);? ? }destroy() {//銷毀ReactDom.unmountComponentAtNode(this.div);this.div.parentNode.removeChild(this.div);? ? }}exportdefault{show:function(children) {? ? ? ? dialog=newDialog();dialog.show(children);? ? },? ? hide:xxxxx};//某組件importDialogfrom'xxx';alert=()=>{Dialog.show(xxxx);}render() {return(<button onClick={this.alert}>點(diǎn)擊彈層</button>)}

第八道菜:火燒肉

render props是現(xiàn)在很流行的一種渲染方式要出,通過回調(diào)函數(shù),渲染子組件农渊,參數(shù)可為父組件的任意屬性值(官網(wǎng)也有相應(yīng)的介紹)新版的contextApi也采用了這個模式患蹂。

很多種場景使用此方式的做法:

//權(quán)限控制組件,只需要封裝一次connect砸紊,//通過render props向子組件傳遞權(quán)限classAuthWidgetextendsComponent{render() {returnthis.props.children(this.props.auth);? ? }}constmapStateToProps=state=>{const{auth}=state;return{ auth:state.auth};};exportdefaultconnect(mapStateToProps)(AuthWidget);//其他組件使用<AuthWidget? ? children={auth=>auth.edit&&<a>編輯</a>}/>//使用antd的form時constTest=({ form, children })=>{returnchildren(form);};constFormTest=Form.create()(Test);classDemoextendsComponent{render() {return(<div>xxxxx<FormTest>{form=>{this.form=form;return(<Form><Form.Item>{getFieldDecorator('field', xxx)(<Input placeholder="請輸入鏈接地址"/>)}</Form.Item></Form>)? ? ? ? ? ? ? ? ? ? }}</FormTest></div>)? ? }}

第九道菜:粉絲白菜蝦仁湯

子組件改變父組件的state方式有很多種传于,可以在父組件設(shè)置一個通用函數(shù),類似:setParentState醉顽,通過子組件回調(diào)處理時沼溜,就可以更方便的統(tǒng)一處理:

//父組件state={? ? data:{}}setParentState=obj=>{this.setState(obj);}//子組件onClick=()=>{this.props.setParentState({ data:xxx });}

第十道菜:麻婆豆腐

永遠(yuǎn)不要直接設(shè)置state的值:this.state.data = { a: 1 }。這個會導(dǎo)致幾個問題: 1:組件不會重新渲染 2:shouldComponentUpdate(nextProps, nextState) 函數(shù)里面 this.state的值是已經(jīng)改變了,和nextState的值相同游添。

舉個栗子:

// wrong

const { data } = this.state;

data.a = 1;? ? // 等價于this.state.data.a = 1;

this.setState({ data }); // shouldComponentUpdate里面觀察到 this.state 和nextState的值是相同的

// 此時函數(shù)里面性能相關(guān)的優(yōu)化是無效的

// correct? 需要用到當(dāng)前state值的寫法

this.setState(state => ({ data: {...state.data, a: 1} }))

如果想學(xué)習(xí)Java工程化系草、高性能及分布式、深入淺出唆涝。性能調(diào)優(yōu)找都、Spring,MyBatis廊酣,Netty源碼分析的朋友可以加我的Java高級程序員群:180705916能耻,群里有阿里大牛直播講解技術(shù),以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費(fèi)分享給大家亡驰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晓猛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凡辱,更是在濱河造成了極大的恐慌戒职,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件透乾,死亡現(xiàn)場離奇詭異洪燥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)续徽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亲澡,“玉大人钦扭,你說我怎么就攤上這事〈残鳎” “怎么了客情?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵其弊,是天一觀的道長。 經(jīng)常有香客問我膀斋,道長梭伐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任仰担,我火速辦了婚禮糊识,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摔蓝。我一直安慰自己赂苗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布贮尉。 她就那樣靜靜地躺著拌滋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猜谚。 梳的紋絲不亂的頭發(fā)上败砂,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音魏铅,去河邊找鬼昌犹。 笑死,一個胖子當(dāng)著我的面吹牛沦零,可吹牛的內(nèi)容都是我干的祭隔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼路操,長吁一口氣:“原來是場噩夢啊……” “哼疾渴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屯仗,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤搞坝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魁袜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桩撮,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年峰弹,在試婚紗的時候發(fā)現(xiàn)自己被綠了店量。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞠呈,死狀恐怖融师,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚁吝,我是刑警寧澤旱爆,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布舀射,位于F島的核電站,受9級特大地震影響怀伦,放射性物質(zhì)發(fā)生泄漏脆烟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一房待、第九天 我趴在偏房一處隱蔽的房頂上張望邢羔。 院中可真熱鬧,春花似錦吴攒、人聲如沸张抄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摹察。三九已至彭则,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晃听。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工鲜侥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涯雅,地道東北人外构。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像域那,于是被迫代替她去往敵國和親咙边。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容