iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 7
0
Modern Web

React鐵人先爆了再說系列 第 8

[08] TodoList程式

  • 分享至 

  • xImage
  •  

今天做了一個TodoList程式當作練習,
首先看到有兩個外部元件, Button元件 和 ListItem元件:

Button.js

import React from 'react'

const Button = (props) => {
  //呼叫的是由上層元件從props.onButtonClick傳入的方法
  return <button onClick={props.onButtonClick}>{props.text}</button>

}

export default Button

先看 Button 這個元件,點擊 Button 時觸發 onclick 方法,裡面是

{props.onButtonClick}

按了它等於呼叫上層元件(父元件)中的方法 onButtonClick,是一個上層元件中的方法定義。

ListItem.js

import React from 'react'

const ListItem = (props) => {
  
  //呼叫的是由上層元件從props.onItemClick傳入的方法
  return <li onClick={props.onItemClick}>{props.text}</li>

}

export default ListItem

ListItem元件 跟 Button 差不多,只是點擊 list 的項目觸發 onclick 後,呼叫的是上層元件中的 onItemClick 方法。

onButtonClickonItemClick 都是函式類型的值,它是在上層元件中設定給它的。在 Button 跟 ListItem 中, onClick 事件觸發時,並不是呼叫自己元件中的方法,而是去呼叫到父元件中定義的方法。

  • onButtonClick 這個方法就是要從列表中新增一個項目
  • onItemClick 這個方法就是要從列表中移除掉被點按的項目

接下來是今天最主要的 TodoList 元件:

TodoList.js

import React, { Component } from 'react'
import ListItem from './ListItem'
import Button from './Button'

class TodoList extends React.Component {

  constructor(props) {

    super(props)

    this.state = {
      items: [],
      inputValue: '',
    }
  }
  
  //下面還有程式碼...
 

import 要用到的項目,使用 constructor 建構 state 的初始值, 有 items:空陣列 和 inputValue:空字串

  handleChange = (e) => {
    this.setState({ inputValue: e.target.value })
  }


  handleAddItem = () => {
    const newItems = [this.state.inputValue, ...this.state.items]

    //按下Button後,加到列表項目中並清空輸入框
    this.setState({
      items: newItems,
      inputValue: '',
    })
  }


  handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      const newItems = [this.state.inputValue, ...this.state.items]

      //按下鍵盤Enter後,加到列表項目中並清空輸入框
      this.setState({
        items: newItems,
        inputValue: '',
      })
    }
  }


  //處理過濾掉其中一個陣列成員的方法
  handleRemoveItem = (id) => {
    const newItems = this.state.items.filter((item, i) => i !== id)

    //整個陣列重新更新
    this.setState({
      items: newItems,
    })
  }
  
  //下面還有程式碼...
  • handleChange 是處理文字輸入框在輸入文字時做出改變用的

  • handleAddItem 是Button被按下時處理的方法,獲取到 inputValue 的值,然後把新的項目加到陣列中,最後把文字輸入框中的文字清空,所以設定 state 中的 inputValue 值為空字串

  • handleKeyDown 是輸入框被按下 Enter 鍵時處理的方法,獲取到的 KeyboardEvent 物件的 key 屬性,判斷按下的是Enter鍵,然後把新的項目加到陣列中,按下 Enter 鍵時,也要把文字輸入框中的文字清空,所以也要設定 state 中的 inputValue 值為空字串

  • handleRemoveItem 並不是給這個元件(TodoList)使用的,而是給包含在其中的子項目元件(ListItem)使用的,當 list 中的項目被點按時,使用 filter 過濾掉這筆資料,再用 setState 更新 items 陣列

render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.inputValue}
          placeholder={"請輸入文字"}
          onChange={this.handleChange}
          onKeyDown={this.handleKeyDown}
        />
        <Button text="新增項目" onButtonClick={this.handleAddItem}></Button>
        <ul>
          {
            this.state.items.map((value, id) => {
              return <ListItem key={value} text={value} onItemClick={() => this.handleRemoveItem(id)} />
            })
          }
        </ul>
      </div>
    )
  }

}

export default TodoList

render() 的部分,相較於之前的 TextInput元件,在文字輸入框的地方,多了一個onKeyDown的事件,它是用來獲取按下鍵盤時的事件用的,觸發 handleKeyDown 方法。

而在下面的是加入了一個 Button ,作用和按下 Enter 鍵差不多,都是新增 List 的項目,只是透過點擊外部元件 Button 去觸發 handleAddItem 方法。

最後<ul>標籤裡面加入了一個使用陣列的map方法,把所有目前的在state 中的 items 項目整個輸出。

這邊有個 key 值,是用於像這種 List 項目,或是有多個同樣的元件在 React 中渲染時使用的,它並不是 props 的成員,而是讓 React 用於識別不同的元件(或DOM元素)使用的。React會要求像這種列表項目時,一定要給key值。

List 項目被點按時觸發 handleRemoveItem 方法,用 id 傳遞了點選項目的索引值,給 handleRemoveItem 裡面使用 filter 過濾掉該筆資料。

執行結果:

在文字輸入框輸入文字後按下 Button 或是 鍵盤Enter鍵,就會把文字加到下面的列表中,每個項目用滑鼠點按一下,會觸發這個項目的刪除


上一篇
[07] 生命週期(Life Cycle)
系列文
React鐵人先爆了再說8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言