HI!大家好,這一篇和前一篇應該會比較輕鬆,畢竟說的都是天天陪伴著大家的語法XD,加上在
JSX
中處理
Element
真的變得很容易上手,因為就和原生的
JavaScript
一樣嘛!沒有地方好苦腦的,哈哈!所以這兩天就當作過了第一個禮拜的門檻,輕鬆一點吧!
for迴圈
那,都第八篇了,
應該也不用說什麼客套話了XD
,就直接進入範例吧!在不使用迴圈的一般情況下,我們可以這樣處理組件列表:
class TodoList extends React.Component{
constructor(props){
super(props)
render(){
let lists = [<li>打文章</li>,<li>寫程式</li>,<li>耍廢</li>]
return (
//JSX中的JS變數要用花括號包著
{lists}
ReactDOM.render(<TodoList />,document.getElementById('root'))
上方將所有的list事項都放lists
陣列中,最後把整個lists
放進<ul>
中,結果會如下:
所以從上面的例子,就可以知道說,只要放進陣列就可以了!沒錯!就是這樣就可以了,所以當我們透過ajax
從後端取得列表資料時,就可以將render()
寫成這樣:
render(){
//假設有個待辦事項的陣列
let arrLists = ['打文章','寫程式','耍廢']
//先建立一個空陣列
let lists = [];
//用迴圈將代辦事項的內容一個個放進空陣列中
for(let i=0;i<=arrLists.length-1;i++){
//記得在JSX中使用JS變數要用花括號包著
lists.push(<li>{arrLists[i]}</li>)
return (
{lists}
雖然上面的寫法已經詮釋完迴圈的基本用法,但是在JavaScript
中的陣列還有個map()
函式,他可以去巡訪陣列中每個位置的值,並將他們傳入function
做處理後傳出,以下快速學習(詳情可以看這裡):
//宣告一個陣列A
let arrA = [1,2,3,4,5]
//宣告另一個陣列B,並對A使用map()讓每個數字都*2放進B中
let arrB = arrA.map(function(num){ return num*2 })
//把陣列B印出來
console.log(arrB) //[2, 4, 6, 8, 10]
好的!學習完後,我們試著用map
改寫render
吧:
render(){
let arrLists = ['打文章','寫程式','耍廢']
//在巡訪時將arrLists用<li>包起來回傳
let lists = arrLists.map(function(list){return <li>{list}</li>})
return (
{lists}
當然如果想要再潮一點用盡ES6
語法,也可以把map
的function
改成箭頭函式:
render(){
let arrLists = ['打文章','寫程式','耍廢']
let lists = arrLists.map((list) => <li>{list}</li>)
return (
{lists}
以上三種方法都會呈現出和第一張圖一樣的結果,至於大家喜歡哪一種方法,就任君挑選囉!
GitHub程式碼連結
GitPage頁面連結
這裡要提到的key
和現在浮現在大家腦裡的key
可能不太一樣,這裡的key
是為了要讓react
好渲染畫面用的。
以待辦事項來說,在我們有一個以上的項目的時候,如果列表的第一行增加了一個待辦事項,那原本待辦事項的位置都會向下移,造成重新渲染畫面,資料少的話還好,但資料一多那效能可能會有感的下降。
為了避免這個情況react
,會再重新渲染畫面之前,去比對key
值,如果相同,那就會略過,不會重新覆蓋DOM
,就像在[筆記][React]關於Components的那件小事這篇文章中提的時間例子一樣,經過比對就只會重新渲染不同的地方而已。
那麼!key
值該怎麼設定呢?這個比大家想像中的還要簡單:
class TodoList extends React.Component{
constructor(props){
super(props)
render(){
//這裡一樣用map把陣列中每個元素都找出來
let lists = this.props.objLists.map((list) =>
/*key值的資料就給唯一值id指定*/
<li key={list.id}>{list.list}</li>)
return (
{lists}
//假設我們拿到的陣列中,有每一個資料的物件
let objLists =
[{id:'a',list:'打文章'},{id:'b',list:'寫程式'},{id:'c',list:'耍廢'}]
//將該陣列用props的方式傳入class中處理
ReactDOM.render(<TodoList objLists={objLists} />,document.getElementById('root'))
雖然看起來很簡單,但是還是有需要注意的地方:
必須是唯一值,像全天下所有key
的意思一樣,必須是唯一react
才能夠比對,如果再是在開發版,有重複的話雖然畫面可以正常渲染,但console
內會出現錯誤提示:
ps.沒設定key
值其實也會有提示:
這個key值並不會被當屬性渲染出來,所以如果要另外操作的話,就得再設定另一個屬性,例如:
render(){
let lists = this.props.objLists.map((list) =>
/*把唯一值也設定到id身上*/
<li key={list.id} id={list.id}>{list.list}</li>)
return (
{lists}
渲染出來的畫面只會有id
不會有key
:
如果沒有使用key
的話,用陣列的索引會是最後最後的下下策:
render(){
//為map增加第二個index的引數,他會記錄目前是第幾個索引
let lists = this.props.objLists.map((list,index) =>
/*將索引設定為key值*/
<li key={index}>{list.list}</li>)
return (
{lists}
但是第三點這個方式不如不要用,因為他每次都會以索引為key
值去判斷,所以當我們在陣列第一個位置增加一筆資料,那原本的項目都會向下移動,索引也會發生變化,等於原本的1
變2
、2
變3
,然後值就全部寫到對應的新key
中,這麼一來就和重新渲染沒什麼兩樣,key
和值也會不斷變動,所以為了效能還是乖乖自行加上唯一值吧!因為以索引當key
就和沒設一樣,只是不會出現錯誤而已。
GitHub程式碼連結
其實長得一樣的GitPage頁面連結
以上是在react
使用迴圈的方法和注意事項,如果有任何問題的話,再麻煩各位大大留言告訴我,我會再把他補充上去的,最後感謝各位大大的觀看
參考文章:
https://reactjs.org/docs/lists-and-keys.html
https://note.pcwu.net/2017/03/23/react-array-key/
https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318