摘要:比如在的時候組件掛載的時候會根據(jù)指定的參數(shù)繼續(xù)向下執(zhí)行,則會在掛載的時候還沒發(fā)生點擊事件就直接執(zhí)行了父組件的函數(shù)。即中轉(zhuǎn)函數(shù)的效果,保證了時的函數(shù)都是并且也防止了子組件在掛載時,順著調(diào)用父組件的函數(shù)從而避免了一系列錯誤。
寫在前面
以前寫Vue寫慣了,心血來潮,寫起了react。
github地址:Close2React
項目使用框架版本主要有 react(15.4.1) + react-dom(15.4.1) + webpack(1.13.3) + axios(0.15.3) + node(6.2.2), 點擊查看項目簡介:一段人人都應(yīng)該知道的從 vue 到 react 的過渡史
目前該項目有兩個分支, half-es6 + master
half-es6和master實現(xiàn)的功能一樣, 實現(xiàn)了CURD + Axios + Others
half-es6的寫法并沒有完全使用es6的class的概念, master是完善了它
現(xiàn)在讓我們快速了解React的事件綁定都有什么坑~
?? ?? ??
// 父組件主要是為了實現(xiàn)tab的切換 const Content = React.createClass({ getInitialState() { return { tabTxt: ["CURD", "Axios", "Others"], choice: 0, //目前激活的tab的下標(biāo) } }, switchChoice(idx){ // 設(shè)置choice this.setState({ choice: idx }) }, renderTabInit(text, idx) { return ({text} ) }, render() { ...... } });
自以為把方法傳入了子組件,就在Tab子組件中直接this.props.choose調(diào)用父組件的方法
const Tab = React.createClass({
render(){
return (
{this.props.children}
)
}
});
結(jié)果瀏覽器打開就爆炸了。boom
正確姿勢大概意思就是說:
我在父組件中的setState在渲染的時候?qū)е铝艘粋€錯誤。React不能更新一個正在變化的state。
組件中的render應(yīng)該是一個帶有state和props的pure function(純函數(shù))。如果不是純函數(shù),構(gòu)造器會產(chǎn)生一些副作用。
比如在render的時候(組件掛載的時候)會根據(jù)props指定的參數(shù)繼續(xù)向下執(zhí)行,則會在掛載的時候(還沒發(fā)生點擊事件)就直接執(zhí)行了父組件的函數(shù)。順便解釋一下pure function
1、給出同樣的參數(shù)值,該函數(shù)總是求出同樣的結(jié)果。該函數(shù)結(jié)果值不依賴任何隱藏信息或程序執(zhí)行處理可能改變的狀態(tài)或在程序的兩個不同的執(zhí)行,也不能依賴來自I/O裝置的任何外部的輸入
2、結(jié)果的求值不會促使任何可語義上可觀察的副作用或輸出,例如易變對象的變化或輸出到I/O裝置
const Tab = React.createClass({
chooseTab() { // 子組件的中轉(zhuǎn)函數(shù)
this.props.choose(this.props.idx); //在這里調(diào)用父組件的函數(shù)
},
render(){
return (
{this.props.children}
)
}
});
這個中轉(zhuǎn)函數(shù)的名詞是我自己取的,只是這樣就能讓點擊事件的函數(shù)變成pure function,就不會在組件掛載的時候就沿著props繼續(xù)向下執(zhí)行,就能避免在掛載組件的時候就直接調(diào)用父組件的setState了。
--
案例2 todolist 的 編輯 & 保存 示例效果圖 錯誤示范// 父組件 const PageA = React.createClass({ getInitialState() { ... }, // 初始化todolist的數(shù)據(jù) componentDidMount(){ ... }, // 掛載組件時的函數(shù) initDidCount() { ... }, // 更新完成的進度 handleTxtChange(event){ // 重點: 當(dāng)input的輸入值變化時調(diào)用這個函數(shù) let index = event.target.getAttribute("data-index"); // 強行得到todolist的index // 這里一定需要index這個參數(shù)作為修改this.state.list時候的下標(biāo) this.state.list[index].text = event.target.value; // 把input的值更新到state上去 this.setState({ list: this.state.list }); this.initDidCount(); // 更新完成進度 }, handleCheckChange(event,idx) { ... }, // checkbox的onChange,和input的onChange一樣 deleteItem(idx) { ... }, // 刪除 initListLi(val,idx) { return () }, render() { ...... } });
這里也會和案例1有同樣的情況,父組件用props傳入的方法里面有setState,如果在子組件的reader中直接用this.props.handleTxtChange 調(diào)用的話,會導(dǎo)致函數(shù)不純。
錯誤姿勢1// 錯誤的父組件1 ... handleTxtChange(event,idx){ // 重點:【錯誤寫法1】 強行傳了兩個參數(shù) console.log(event, idx); // 在控制臺上輸出結(jié)果 this.state.list[idx].text = event.target.value; // 把input的值更新到state上去 this.setState({ list: this.state.list }); this.initDidCount(); // 更新完成進度 }, ... // 錯誤的子組件1 ... render (){ return (
{this.props.text}
} ...你會發(fā)現(xiàn),你想要給props的方法里傳的自定義參數(shù)index能正常獲取,
而框架自帶參數(shù)event怎么都拿不到,
結(jié)果只能如下,event會變成undefined。
// 錯誤的父組件2 ... handleTxtChange(event){ // 重點:【錯誤寫法2】 只有框架自帶參數(shù)event console.log(event.target); // 在控制臺上輸出結(jié)果 let index = event.target.getAttribute("data-index"); // 強行拿到標(biāo)簽上的自定義屬性 this.state.list[index].text = event.target.value; // 把input的值更新到state上去 this.setState({ list: this.state.list }); this.initDidCount(); // 更新完成進度 }, ... // 錯誤的子組件2 ... render (){ return (
{this.props.text}
} ...當(dāng)發(fā)現(xiàn)多傳了參數(shù),導(dǎo)致了框架自帶的默認(rèn)參數(shù)event怎么都取不到的時候,
決定不傳參數(shù),用其他歪門邪道(比如自定義屬性)拿到想要的參數(shù)。
在input中輸入內(nèi)容,結(jié)果如下。雖然正確,但這樣寫感覺實在是不夠智能。
總之,這樣寫雖然解決了問題,但我還是覺得姿勢還是不對。
// 正確的父組件 ... handleTxtChange(event,idx){// 重點:【正確姿勢】 不僅帶了框架默認(rèn)參數(shù)event,還帶了自定義參數(shù) this.state.list[idx].text = event.target.value; this.setState({ // 最正常的賦值寫法 list: this.state.list }); this.initDidCount(); }, ... // 正確的子組件 ... handleTxt(event) { // 用一個中轉(zhuǎn)函數(shù)來存onChange時會調(diào)用的父組件的函數(shù) // 并加上任意的參數(shù) this.props.handleTxtChange(event, this.props.index); }, render (){ return (
{this.props.text}
} ...案例3如果這樣寫的話,是達到了和案例1一樣的效果。
即中轉(zhuǎn)函數(shù)的效果,保證了render時的函數(shù)都是pure function
并且也防止了子組件在掛載時,render順著this.props.function調(diào)用父組件的函數(shù)
從而避免了一系列錯誤。
案例3純粹是為了演示一個增加操作,在增加一條記錄后,需要清空input的內(nèi)容時踩的坑
// 父組件 addLiItem(obj) { this.state.list.push(obj); // 沒啥好說,就是添加一個元素到list中去 this.setState({ list: this.state.list }); this.initDidCount(); },
// 子組件 const Add = React.createClass({ getInitialState() { return { addValue: "", addStatus: false } }, handleAddChange(event) { this.setState({ addValue: event.target.value }) }, add(){ this.props.addLiItem({ text: this.state.addValue, status: false }); this.setState({ //【重點部分】 addValue: "" }, ()=>{ this.refs.addIpt.value = ""; // 利用ref操作dom }); }, // 如果只是setState的時候發(fā)現(xiàn)完成沒辦法達到清空的效果 // 這時候的【正確姿勢】是去操作dom,一定要操作dom render() { return (// 定義了一個ref是addIpt的input標(biāo)簽) } });
--
總結(jié)為了盡可能使用pure function,也為了保證掛載的時候不要出問題
在子組件需要調(diào)用父組件的this.props.function的時候
盡可能使用中轉(zhuǎn)函數(shù)
你懂得~~
github地址:Close2React
我是嘉寶Appian,一個賣萌出家的算法妹紙。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86607.html
摘要:本文針對的讀者具備性能優(yōu)化的相關(guān)知識雅虎條性能優(yōu)化原則高性能網(wǎng)站建設(shè)指南等擁有實戰(zhàn)經(jīng)驗。這種機制能減少瀏覽器次數(shù),從而提高性能。僅會檢查該和它的子,當(dāng)你確定當(dāng)前操作僅影響它們時,用可以稍微提升性能。 搬運自: http://atian25.github.io/2014/05/09/angular-performace/ 不知不覺,在項目中用angular已經(jīng)半年多了,踩了很多坑...
摘要:年前公司由一個項目是使用來開發(fā)的所以遇到了一些問題比較影響開發(fā)進程的就是路由問題了實際上就是這個組件比較難懂這里給大家講解一下希望大家少踩點坑另外本篇文章使用的是環(huán)境主要講解的還是如何使用記錄中路由的狀態(tài)但是會穿插一些小內(nèi)容這里雖然講到的是 年前公司由一個項目是使用 ReactNative 來開發(fā)的所以遇到了一些問題,比較影響開發(fā)進程的就是路由問題了,實際上就是 ReactNaviga...
摘要:功能三滴滴費用計算古人云細(xì)節(jié)決定成敗,一個良好的微信小程序往往就是一些細(xì)節(jié)打動人心,居然是模仿,雖做不到百分百,至少還是很希望一模一樣。 最近時常感嘆道:時間總是那么的快,轉(zhuǎn)瞬即逝。對于像我這種剛?cè)腴T的小生來講,技術(shù)每天都在更新,框架也層出不窮,有時候還沒弄懂這個知識大牛們又推出了更好的技術(shù)。當(dāng)然學(xué)習(xí)好的技術(shù)也是十分重要的。但是在學(xué)習(xí)之后怎樣才能夠得到自己想要的呢,一個好的建議便是靜...
摘要:第二步就是調(diào)用,我在文件夾簡歷了個的文件,方便管理。然后在里面引入至此,安裝基本完成,下面介紹這個東西的用法。其實這東西用法簡單的一比,就是幾個屬性而已。例如然后在組件中直接調(diào)用這樣就直接運行了這個方法。 項目終于做完了,博客也很久沒更新了,寫下這個項目用到的一些知識,以后大家也少踩點坑第一步當(dāng)然還是安裝了,這里只介紹npm的安裝方法,別的請自行百度。 npm install vuex...
摘要:的網(wǎng)站仍然使用有漏洞庫上周發(fā)布了開源社區(qū)安全現(xiàn)狀報告,發(fā)現(xiàn)隨著開源社區(qū)的日漸活躍,開源代碼中包含的安全漏洞以及影響的范圍也在不斷擴大。與應(yīng)用安全是流行的服務(wù)端框架,本文即是介紹如何使用以及其他的框架來增強應(yīng)用的安全性。 showImg(https://segmentfault.com/img/remote/1460000012181337?w=1240&h=826); 前端每周清單專注...
閱讀 2478·2021-11-17 09:33
閱讀 765·2021-11-04 16:13
閱讀 1336·2021-10-14 09:50
閱讀 702·2019-08-30 15:53
閱讀 3668·2019-08-30 14:18
閱讀 3273·2019-08-30 14:14
閱讀 2102·2019-08-30 12:46
閱讀 3187·2019-08-26 14:05