iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0

大家好!今天的目標是實現一個基本但非常重要的功能,新增一個表單來加入新的待辦事項。

一個表單最基本的會有一個輸入框還有一個按鈕,我們將會示範如何使用 React Native 中的表單元件,例如 TextInput,會用來收集使用者輸入的資料,並把它們保存到我們的待辦事項列表中。

在我們開始之前,讓我們先瞭解一下今天的程式碼。這是一個基本的待辦事項應用程式,我們有一個 inputText 的狀態來保存用戶輸入的文字,和一個 todos 的狀態來保存待辦事項的列表。每當用戶輸入一個新的待辦事項,我們會把它新增到 todos 的列表中。

使用 TextInput 做一個輸入框

TextInput 是 React Native 提供的一個基本元件,讓我們能夠讓使用者輸入一些文字。它相當於網頁開發中的 <input type="text"> 元素。

讓我們把 TextInput 加進程式碼中:

export default function App() {
  return (
    <View style={styles.container}>
      <TextInput
        value={}
        placeholder='請輸入事項'
        onChangeText={}
      />
      <StatusBar style='auto' />
    </View>
  )
}

接下來一一介紹這個元件所需要的一些 props 是什麼。

value 是這個 TextInput 當前輸入的值,等一下會使用 usestate 綁定到我們的狀態。placeholder 則是當這個輸入框是空的時候會顯示的提示文字。onChangeText 是當這個輸入框的值變化時會被調用的函數。

將文字存到 useState 中

當使用者在 TextInput 裡面打字的時候,我們想要把他們輸入的文字收集起來,並保存到我們的狀態中。這時候就要通過建立一個函式和 useState 這個 Hook 來實現。

import { useState } from 'react'

export default function App() {
  const [inputText, setInputText] = useState('')

  const handleInputText = (text) => {
    setInputText(text)
  }
  
  return (
    <View style={styles.container}>
      <TextInput
        value={inputText}
        placeholder='請輸入事項'
        onChangeText={handleInputText}
      />
      <StatusBar style='auto' />
    </View>
  )  
}

在上面的程式碼中,handleInputText 這個函數,它會被當 TextInput 的值改變的時候調用,並且它會接收到一個參數,就是 TextInput 的當前值。

把新的待辦事項加入到列表中

輸入完文字後,由於在手機 App 上並沒有像網頁那樣可以透過按下 Enter 鍵來做一個新增的動作,所以我們要建立一個按鈕來做這件事。
我們可以用 TouchableOpacity 來製作按鈕,並且使用 useState 來新增一個列表的狀態。

const [todos, setTodos] = useState([])

const handleAddItem = () => {
  setTodos([
    ...todos,
    {
      id: todos.length,
      text: inputText,
      checked: false
    }
  ])
}

return (
    <View style={styles.container}>
      <TextInput
        value={inputText}
        placeholder='請輸入事項'
        onChangeText={handleInputText}
      />
      <TouchableOpacity onPress={handleAddItem}>
        <Text>新增</Text>
      </TouchableOpacity>
      <StatusBar style='auto' />
    </View>
)  

當使用者輸入了一個新的待辦事項,並點擊了新增按鈕之後,我們想要把這個新的待辦事項加入到我們的 todos 列表中。

這是通過 handleAddItem 實現的。這個函式會建立一個新的待辦事項的物件,然後用 setTodos 把這個新的待辦事項加入到 todos 列表中。

這邊說明一下建立的物件,裡面的 key 分別有 id、text 和 checked。id 是為了之後可以方便去比對做刪除與編輯,而 text 就是我們輸入並且會顯示在畫面上的文字,最後 checked 則是可以做一個表示完成與否的一個狀態。

使用 StyleSheet 設計界面

最後我們要來美化一下今天做的表單,由於樣式設計不會是我們這個系列的重點,所以大家可以自己發揮,或者可以參考我的樣式,以下是今天完整的程式碼:

import { useState } from 'react'
import { StatusBar } from 'expo-status-bar'
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  SafeAreaView
} from 'react-native'

export default function App() {
  const [inputText, setInputText] = useState('')
  const [todos, setTodos] = useState([])

  const handleInputText = (text) => {
    setInputText(text)
  }

  const handleAddItem = () => {
    setTodos([
      ...todos,
      {
        id: todos.length,
        text: inputText,
        checked: false
      }
    ])
  }

  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.title}>Todos</Text>
      <View style={styles.inputArea}>
        <TextInput
          value={inputText}
          placeholder='請輸入事項'
          onChangeText={handleInputText}
          style={styles.input}
        />
        <TouchableOpacity onPress={handleAddItem} style={styles.button}>
          <Text>新增</Text>
        </TouchableOpacity>
      </View>
      <StatusBar style='auto' />
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center'
  },
  title: {
    fontSize: 30,
    fontWeight: 500,
    alignSelf: 'flex-start',
    marginBottom: 10,
    color: '#eae6e6'
  },
  inputArea: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 10
  },
  input: {
    borderColor: '#bcb9b9',
    borderWidth: 1,
    borderRadius: 5,
    height: '100%',
    width: '80%',
    paddingHorizontal: 15,
    fontSize: 20,
    backgroundColor: '#fff'
  },
  button: {
    backgroundColor: '#fff',
    padding: 10,
    borderRadius: 5
  }
})

總結

今天展示了如何在 React Native 中建立一個簡單的表單來收集用戶的輸入,並把它加入到一個待辦事項的列表狀態中。

由於現在寫在 App.js 的程式碼有點多,所以明天會做好元件模組化,讓之後的開發更順暢。

明天見!


上一篇
Day 3 - 介紹 React Native 元件以及樣式設定
下一篇
Day 5 - 使用 context 和 useReducer 來管理與傳遞資料狀態
系列文
掌握 React Native 與 Expo:30天雙打,新手也能精通跨平台開發!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言