iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 6
0

這兩天會開始做一點小東西,做個react的總結,為了實作上的方便性,可能會用上前幾個文章沒講到的語法但不會都詳細說明,我會簡單的說一下功能,有興趣的再麻煩去看看文章跟文件。

首先說一下今天這篇文章的目標,是做出一個具有新增功能的List元件。

為了實作上的方便性,我們把list.js內改成以Class的語法來生成我們的元件,在功能性上會比原本直接匯出render的涵式還要強,可以用在方法中使用this跟state。
/pages/index.js

import React from "react"
import List from "../components/list"

const foods = [{ id: 1, name:'Apple'}, { id: 2, name:'Banana'}, { id: 3, name:'Cake'}];

export default () => (
  <div> 
    <List itemData={foods}></List>
  </div>
)

在主畫面中,我們直接擺入Listist元件,並把props給傳進去。

/components/List.js

import React from "react"

class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      itemData: props.itemData,
      inputValue: ""
    };
    this.inputChangeHandler = this.inputChangeHandler.bind(this);
    this.clickHandler = this.clickHandler.bind(this);
  }

  clickHandler(e) {
    const addValue = this.state.inputValue;
    const newItemData = this.state.itemData;
    const dataId = Math.max.apply(null, (newItemData.map(p => p.id)))+1;
    newItemData.push({id: dataId, name: addValue});
    
    this.setState({itemData: newItemData});
    this.setState({inputValue: ''});
  }

  inputChangeHandler(e) {
    const value = e.target.value;
    this.setState({inputValue: value});
  }

  render(){
    return(
      <div>
        <input type="text" name="name" onChange={this.inputChangeHandler} value={this.state.inputValue}/>
        <button onClick={this.clickHandler}>新增</button>
        <ul>
          {this.state.itemData.map((data)=>(<li key={data.id}>{data.name}</li>))}
        </ul>
      </div>
    )
  }
}

export default List;

List這個元件裡,我們第一次用render函式去定義我們的組件。
畫面上,有一個input跟一個button,我們另一了兩個事件觸發

  • inputChangeHandler(inpuptinpupt onChange(內容改變時)): 它做的事主要是去更新我們的this.state.inputValue這個狀態的值,因為react屬於單向綁定,修改state時,會重新去將資料render到畫面上,但更新畫面時,不會主動地去更新資料,所以當input的內容改變時,我們會去主動的更新。
  • clickHandler: 當按鈕按下去,它做了兩件事,第一件事是將原本的itemDate的值加入inputValue,第二件事就是將inputValue的值清空。

而在上述例子中,會發現我們都使用setState方法,並且將我們的資料都放在this.state裡面,原因是因為當資料進行更動時,我們需要重新去觸發渲染,setState便是提供這樣的功能,然而它是一個異步的函式,這代表著我們必須去注意執行的順序,並且不能期待state馬上改變。

此外,props在這個class裡面的使用方法相同,在物件生成時,我們會利用constructor對物件和資料進行初始化,或將props拿來初始化我們元件的state。

還有一點值得注意的是,在constructor中,我們將兩個事件監聽的handler的this用bind去進行綁定,這個步驟跟js的特性有關係,因為handler內的this未必會永遠指向這個元件,而是觸發它的元素,比如說,若我們沒有進行綁定,那當按鈕按下時,它的this可能就會指向按鈕本身,然後程式就會出問題。
解決這個問題的另一個方法,可以使用箭頭函式,這樣的話方法內的this就會指向物件本身了~

https://ithelp.ithome.com.tw/upload/images/20190910/20111629CGeteKQB0R.png

這樣我們便完成了一個簡單的新增功能了。
這篇中多了一些東西,但去翻翻react的文檔後就會發現它的核心概念其實不困難,指是使用上必須清楚它的運作原理。雖然還在熟悉階段,但隨著把文檔的內容慢慢地吸收,也慢慢的可以更了解它的運作方式了。
期間還不斷發先自己之前寫作的內容並進行修改((汗,希望犯的錯可以越來越少。

明天希望在這個簡單的範例中加入一個刪除功能。


上一篇
Day5. React的基本用法 (四)
下一篇
Day7. React的基本用法 (六)
系列文
用Gatsby.js做出一個簡單的部落格28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
yne711520
iT邦見習生 ‧ 2019-09-10 22:47:51

感謝分享

0
yne711520
iT邦見習生 ‧ 2019-09-10 22:48:01

為甚麼List這個跟之前的長得不一樣

這邊是用class的寫法來做匯出噢
寫法不同,但都能匯出react的元件

我要留言

立即登入留言