react實踐

React 最佳實踐一、 React 與 AJAX
React 只負責處理 View 這一層,它本身不涉及網絡請求 /AJAX:

第一,用什么技術從服務端獲取數據;
第二,獲取到的數據應該放在 react 組件的什么位置。

事實上是有很多的:fetch()、fetch polyfill、axios...
其中最需要我們關注的是window.fetch(),它是一個簡潔、標準化的 javascript 的 Ajax API 。
在 Chrome 和 Firefox 中已經可以使用,如果需要兼容其他瀏覽器,可以使用 fetch polyfill 。
ajax實踐:

1.所有的數據請求和管理都存放在唯一的一個根組件讓父組件 /根組件集中發送所有的 ajax 請求,
把從服務端獲取的數據統一存放在這個組件的 state 中,再通過 props 把數據傳給子組件。
這種方法主要是針對組件樹不是很復雜的小型應用。缺點就是當組件樹的層級變多了以后,
需要把數據一層一層地傳給子組件,寫起來麻煩,性能也不好。2.設置多個容器組件專門處理數據請求和管理其實跟第一種方法類似,只不過設置多個容器組件來負責數據請求和狀態管理。
這里我們需要區分兩種不同類型的組件,
一種是展示性組件( presentational component ),
另一種是容器性組件( container component )。
展示性組件本身不擁有任何狀態,所有的數據都從容器組件中獲得,在容器組件中發送 ajax 請求。3.使用 Redux 或 Relay 的情況Redux 管理狀態和數據, Ajax 從服務器端獲取數據,所以很顯然當我們使用了 Redux 時,
應該把所有的網絡請求都交給 redux 來解決。具體來說,應該是放在Async Actions。
如果用其他類 Flux 庫的話,解決方式都差不多,都是在 actions 中發送網絡請求。

把計算和條件判斷都交給render()方法吧

echarts
概覽頁面 -》 echats圖修改的時候犯了個錯 yield put({ type: ' DescribeInvadeTrend' }); --》
發現沒有請求 咋回事!!!! 注意觀察代碼...

React setState
setState(updater, callback)這個方法是用來告訴react組件數據有更新,有可能需要重新渲染。它是異步的,react通常會集齊一批需要更新的組件,然后一次性更新來保證渲染的性能,所以這就給我們埋了一個坑:
那就是在使用setState改變狀態之后,立刻通過this.state去拿最新的狀態往往是拿不到的。
所以第一個使用要點就是:如果你需要基于最新的state做業務的話,可以在componentDidUpdate或者setState的回調函數里獲取。(注:官方推薦第一種做法)
設想有一個需求,需要在在onClick里累加兩次,如下:

onClick = () => {this.setState({ index: this.state.index + 1 });this.setState({ index: this.state.index + 1 });}

在react眼中,這個方法最終會變成

Object.assign(previousState,{index: state.index+ 1},{index: state.index+ 1},...
)

由于后面的數據會覆蓋前面的更改,所以最終只加了一次.所以如果是下一個state依賴前一個state的話,推薦給setState傳function

onClick = () => {this.setState((prevState, props) => {return {quantity: prevState.quantity + 1};});this.setState((prevState, props) => {return {quantity: prevState.quantity + 1};});
}

以上是使用setState的兩個注意事項,接下來我們來看看setState被調用之后,更新組件的過程:

ReactBaseClassses.js
ReactComponent.prototype.setState = function (partialState, callback) {//  將setState事務放進隊列中this.updater.enqueueSetState(this, partialState);if (callback) {this.updater.enqueueCallback(this, callback, 'setState');}
};

這里的partialState可以傳object,也可以傳function,它會產生新的state以一種Object.assgine()的方式跟舊的state進行合并。

二、enqueueSetState

enqueueSetState: function (publicInstance, partialState) {// 獲取當前組件的instancevar internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState');// 將要更新的state放入一個數組里var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);queue.push(partialState);//  將要更新的component instance也放在一個隊列里enqueueUpdate(internalInstance);}
.

..消化...

state和props
React 的核心思想是組件化的思想,而React 組件的定義可以通過下面的公式描述:
UI = Component(props, state)
不是對props 和state 基本用法的介紹,而是嘗試從更深層次解釋props 和 state,并且歸納使用它們時的注意事項。
一句話概括,props 是組件對外的接口,state 是組件對內的接口。
組件的props 和 state都和組件最終渲染出的UI直接相關。
組件中用到的一個變量是不是應該作為組件state,可以通過下面的4條依據進行判斷:

  1. 這個變量是否是通過props從父組件中獲取?如果是,那么它不是一個狀態。?
  2. 這個變量是否在組件的整個生命周期中都保持不變?如果是,那么它不是一個狀態。?
  3. 這個變量是否可以通過state 或props 中的已有數據計算得到?如果是,那么它不是一個狀態。?
  4. 這個變量是否在組件的render方法中使用?如果不是,那么它不是一個狀態。這種情況下,這個變量更適合定義為組件的一個普通屬性(除了props 和 state以外的組件屬性 ),例如組件中用到的定時器,就應該直接定義為this.timer,而不是this.state.timer。?
    不能依賴當前的props計算下個state,因為props的更新也是異步的。
Object.assign(previousState,{quantity: this.state.quantity + 1},{quantity: this.state.quantity + 1}
)

當點擊一次購買按鈕,購買的數量就會加1,如果我們連續點擊了兩次按鈕,就會連續調用兩次this.setState({quantity: this.state.quantity + 1})

// 正確
this.setState((preState, props) => ({counter: preState.quantity + 1; 
}))

State 的更新是一個淺合并(Shallow Merge)的過程。
例如,一個組件的state為:

this.state = {title : 'React',content : 'React is an wonderful JS library!'
}
this.setState({title:?'Reactjs'});
React會合并新的title到原來的組件state中,同時保留原有的狀態content,合并后的state為:
{title : 'Reactjs',content : 'React is an wonderful JS library!'
}

State與Immutable
React官方建議把state當作不可變對象,一方面是如果直接修改this.state,組件并不會重新render;另一方面state中包含的所有狀態都應該是不可變對象。
如有一個數組類型的狀態books,當向books中增加一本書時,使用數組的concat方法或ES6的數組擴展語法(spread syntax):

// 方法一:使用preState、concat創建新數組
this.setState(preState => ({books: preState.books.concat(['React Guide']);
}))// 方法二:ES6 spread syntax
this.setState(preState => ({books: [...preState.books, 'React Guide'];
}))
當從books中截取部分元素作為新狀態時,使用數組的slice方法:
// 使用preState、slice創建新數組
this.setState(preState => ({books: preState.books.slice(1,3);
}))

當從books中過濾部分元素后,作為新狀態時,使用數組的filter方法:

this.setState(preState => ({books: preState.books.filter(item => {return item != 'React'; });
}))

注意不要使用push、pop、shift、unshift、splice等方法修改數組類型的狀態,因為這些方法都是在原數組的基礎上修改,而concat、slice、filter會返回一個新的數組。

狀態的類型是簡單對象(Plain Object)

this.state = {owner = {name: '老干部',age: 30}  
}
this.setState(preState => ({owner: Object.assign({}, preState.owner, {name: 'Jason'});
}))
//第一種方法
this.setState(preState => ({owner: {...preState.owner, name: 'Jason'};
}))
//第二種方法

總結一下,創建新的狀態的關鍵是,避免使用會直接修改原對象的方法,而是使用可以返回一個新對象的方法。當然,也可以使用一些Immutable的JS庫,如Immutable.js,實現類似的效果。
那么,為什么React推薦組件的狀態是不可變對象呢?一方面是因為不可變對象方便管理和調試,了解更多可參考這里: http://redux.js.org/docs/faq/ImmutableData.html#benefits-of-immutability
另一方面是出于性能考慮,當組件狀態都是不可變對象時,我們在組件的shouldComponentUpdate方法中,僅需要比較狀態的引用就可以判斷狀態是否真的改變,從而避免不必要的render方法的調用。當我們使用React 提供的PureComponent時,更是要保證組件狀態是不可變對象,否則在組件的shouldComponentUpdate方法中,狀態比較就可能出現錯誤。
porps的改變為什么是異步的? ????????

React頂級API

React.Component
class Greeting extends React.Component {render() {return <h1>Hello, {this.props.name}</h1>}
}
ReactDOM.render(<Greeting name={"zhangyatao"}/>,document.getElementById('root)
)

React.PureComponet
它實現了shouldComponentUpdate()對props和state的進行淺比較。
React.PureComponent的shouldComponentUpdate()僅會對對象進行淺比較,如果對象包含復雜的數據結構,對于深層次的差異有可能會產生false-negatives(假陰性,相當于醫院中的錯診)。

React.Children
React.children提供了處理this.props.children中那些不透明的數據結構的一些工具函數。

React.Children.map
React.Children.map(children,?function[(thisArg))
React.Children.forEach(children,?function[(thisArg)])
和React.Children.map相同,只不過不會返回一個數組。

React.Children.count
React.Children.count(children)
返回children中的組件總數。

React.Children.toArray
React.Children.toArray(children)
將子元素中的不透明數據結構作為一個一維數組返回。如果你想在render方法中操作children集合,特別是如果你想在傳遞它之前重新排序或切割this.props.children,這個方法將非常有用。

React.PropTypes
React.PropTypes是一系列類型驗證器的集合,可以與組件的propTypes對象一起使用,以驗證傳遞到組件的props。

深入理解JSX
從根本上講,JSX就是提供了一個React.createElement(component, props, ...children)函數的語法糖。就像下面的JSX代碼:

<MyButton color="blue" shadow={2}>Click Me
</MyButton>

經過編譯后為:

React.createElement(MyButton,{color: 'blue', shadow: 2},'Click Me'
)
<div className="sidebar"?/>

經過編譯后為:

React.createElement('div',{className: 'sidebar'},null
)

如果你想測試一些特定的JSX是如何轉換成JavaScript的話,你可以試試在線Babel編譯器。
由于JSX編譯的本質是對React.createElement的調用,因此React庫也必須始終在JSX代碼的作用域中。
還可以使用JSX中的點表示符來引用React組件

const MyComponents = {DatePicker(props) {return <div>這里有一個顏色為{props.color}的日期選擇器</div>}
};function BlueDataPicker(props) {return <MyComponents.DatePicker color="blue" />
}

字符串直接量

<MyComponent message="hi " /><MyComponent message={'hi'} />
<MyComponent message='&lt;3' /><MyComponent message={'<3'} />

Props傳遞
如果你有一個對象類似的數據作為props,并且想在JSX中傳遞它,你可以使用...作為一個“spread”運算符傳遞整個props對象。 這兩個組件是等效的:

function App() {return <Greeting firstName="yatao" lastName="zhang" />;
}function App() {const props = {firstName: 'yatao', lastName: 'zhang'};return <Greeting {...props} />;
}

JSX中的子元素和子組件

function MyComponent(props) {return <div>{props.children}<div>; //=> <div>hello</div>
}

JSX會刪除行的開始和結尾處的空格。 它也會刪除中間的空行。 與標簽相鄰的空行被會被刪除;
在字符串文本中間出現的空行會縮合成一個空格。 所以這些都渲染相同的事情:布爾值、null、undefined在渲染時會被自動忽略

<div></div><div>{false}</div><div>{null}</div><div>{true}</div>

如果你想要一個值如false,true,null或undefined出現在輸出中,你必須先將它轉換為字符串:

react性能查看工具
在最新的React16版本中,我們可以直接在url后加上?react_pref,就可以在chrome瀏覽器的performance,我們可以查看User Timeing來查看組件的加載時間。

ps: 關于key的使用
關于key的使用我們要注意的是,這個key值要穩定不變的,就如同身份證號之于我們是穩定不變的一樣。
一個常見的錯誤就是,拿數組的的下標值去當做key,這個是很危險的,代碼如下,我們一定要避免。
將key設置為一個特殊字段,保證其唯一性

其他的檢測工具

react-perf-tool?為React應用提供了一種可視化的性能檢測方案,該工程同樣是基于React.addons,但是使用圖表來顯示結果,更加方便。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388399.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么樣的代碼是好代碼_什么是好代碼?

什么樣的代碼是好代碼編碼最佳實踐 (Coding Best-Practices) In the following section, I will introduce the topic at hand, giving you a sense of what this post will cover, and how each argument therein will be approached. Hopefully, this will help you decide w…

nginx比較apache

話說nginx在大壓力的環境中比apache的表現要好&#xff0c;于是下載了一個來折騰一下。 下載并編譯安裝&#xff0c;我的編譯過程有點特別&#xff1a; 1。去除調試信息&#xff0c;修改$nginx_setup_path/auto/cc/gcc這個文件&#xff0c;將 CFLAGS"$CFLAGS -g" …

計算機主板各模塊復位,電腦主板復位電路工作原理分析

電源、時鐘、復位是主板能正常工作的三大要素。主板在電源、時鐘都正常后&#xff0c;復位系統發出復位信號&#xff0c;主板各個部件在收到復位信號后&#xff0c;同步進入初始化狀態。如圖7-11所示為復位電路的工作原理圖&#xff0c;各個十板實現復位的電路不盡相同&#xf…

Docker制作dotnet core控制臺程序鏡像

(1)首先我們到某個目錄下&#xff0c;然后在此目錄下打開visual studio code. 2.編輯docker file文件如下: 3.使用dotnet new console創建控制臺程序; 4.使用docker build -t daniel/console:dev .來進行打包; 5.啟動并運行鏡像; 6.我們可以看到打包完的鏡像將近2G,因為我們使用…

【362】python 正則表達式

參考&#xff1a;正則表達式 - 廖雪峰 參考&#xff1a;Python3 正則表達式 - 菜鳥教程 參考&#xff1a;正則表達式 - 教程 re.match 嘗試從字符串的起始位置匹配一個模式&#xff0c;如果不是起始位置匹配成功的話&#xff0c;match()就返回none。 re.search 掃描整個字符串并…

在Python中使用Twitter Rest API批量搜索和下載推文

數據挖掘 &#xff0c; 編程 (Data Mining, Programming) Getting Twitter data獲取Twitter數據 Let’s use the Tweepy package in python instead of handling the Twitter API directly. The two things we will do with the package are, authorize ourselves to use the …

第一套數字電子計算機,計算機試題第一套

《計算機試題第一套》由會員分享&#xff0c;可在線閱讀&#xff0c;更多相關《計算機試題第一套(5頁珍藏版)》請在人人文庫網上搜索。1、計算機試題第一套1、計算機之所以能自動運算,就是由于采用了工作原理。A、布爾邏輯。B 儲存程序。C、數字電路。D,集成電路答案選B2、“長…

Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

一&#xff0c;環境說明 操作系統是Windows7家庭版&#xff08;有點不專業哦&#xff0c;呵呵&#xff01;&#xff09;&#xff0c;JDK是1.6的版本&#xff0c; Tomcat是apache-tomcat-6.0.35-windows-x86&#xff0c;下載鏈接&#xff1a;http://tomcat.apache.org/ Nginx…

git 版本控制(一)

新建代碼庫repository 1、在當前目錄新建一個git代碼庫 git init git init projectname 2、下載一個項目&#xff0c;如果已經有了遠端的代碼&#xff0c;則可以使用clone下載 git clone url 增加/刪除/改名文件 1、添加指定文件到暫存區 git add filename 2、添加指定目錄到暫…

rollup學習小記

周末在家重構網關的Npm包&#xff0c;用到了rollup&#xff0c;記下筆記 rollup適合庫library的開發&#xff0c;而webpack適合應用程序的開發。 rollup也支持tree-shaking&#xff0c;自帶的功能。 package.json 也具有 module 字段&#xff0c;像 Rollup 和 webpack 2 這樣的…

大數據 vr csdn_VR中的數據可視化如何革命化科學

大數據 vr csdnAstronomy has become a big data discipline, and the ever growing databases in modern astronomy pose many new challenges for analysts. Scientists are more frequently turning to artificial intelligence and machine learning algorithms to analyze…

object-c 日志

printf和NSlog區別 NSLog會自動加上換行符&#xff0c;不需要自己添加換行符&#xff0c;NSLog會加上時間和進程信息&#xff0c;而printf僅將輸入的內容輸出不會添加任何額外的東西。兩者的輸入類型也是有區別的NSLog期待NSString*&#xff0c;而printf期待const char *。最本…

計算機真正管理的文件名是什么,計算機題,請大家多多幫忙,謝謝

4、在資源管理器中&#xff0c;若想顯示文件名、文件大小和文件類型&#xff0c;應采用什么顯示方式。( )A、小圖標顯示 B、列表顯示 C、詳細資料顯示 D、縮略圖顯示5、在EXCEL中&#xff0c;可以依據不同要求來提取和匯總數據&#xff0c;4、在資源管理器中&#xff0c;若想顯…

小a的排列

鏈接&#xff1a;https://ac.nowcoder.com/acm/contest/317/G來源&#xff1a;牛客網小a有一個長度為nn的排列。定義一段區間是"萌"的&#xff0c;當且僅當把區間中各個數排序后相鄰元素的差為11 現在他想知道包含數x,yx,y的長度最小的"萌"區間的左右端點 …

Xcode做簡易計算器

1.創建一個新項目&#xff0c;選擇“View-based Application”。輸入名字“Cal”&#xff0c;這時會有如下界面。 2.選擇Resources->CalViewController.xib并雙擊&#xff0c;便打開了資源編輯對話框。 3.我們會看到幾個窗口。其中有一個上面寫著Library&#xff0c;這里…

計算機 編程 教程 pdf,計算機專業教程-第3章編程接口介紹.pdf

下載第3章 編程接口介紹? DB2 UDB應用程序概述? 嵌入S Q L編程? CLI/ODBC應用程序? JAVA應用程序? DAO 、R D O 、A D O應用程序本章將介紹對DB2 UDB 可用的編程方法及其特色&#xff0c;其中一些方法附有簡單的例子&#xff0c;在這些例子中&#xff0c;有些并不是只適用…

導入數據庫怎么導入_導入必要的庫

導入數據庫怎么導入重點 (Top highlight)With the increasing popularity of machine learning, many traders are looking for ways in which they can “teach” a computer to trade for them. This process is called algorithmic trading (sometimes called algo-trading)…

windows查看系統版本號

windows查看系統版本號 winR,輸入cmd&#xff0c;確定&#xff0c;打開命令窗口&#xff0c;輸入msinfo32&#xff0c;注意要在英文狀態下輸入&#xff0c;回車。然后在彈出的窗口中就可以看到系統的具體版本號了。 winR,輸入cmd&#xff0c;確定&#xff0c;打開命令窗口&…

02:Kubernetes集群部署——平臺環境規劃

1、官方提供的三種部署方式&#xff1a; minikube&#xff1a; Minikube是一個工具&#xff0c;可以在本地快速運行一個單點的Kubernetes&#xff0c;僅用于嘗試Kubernetes或日常開發的用戶使用。部署地址&#xff1a;https://kubernetes.io/docs/setup/minikube/kubeadm Kubea…

更便捷的畫決策分支圖的工具_做出更好決策的3個要素

更便捷的畫決策分支圖的工具Have you ever wondered:您是否曾經想過&#xff1a; How did Google dominate 92.1% of the search engine market share? Google如何占領搜索引擎92.1&#xff05;的市場份額&#xff1f; How did Facebook achieve 74.1% of social media marke…