iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

使用者在操作 App 的過程中,某些行為例如刪除資料,如果讓使用者直接刪除,這可能會導致重要資料的遺失。

為了避免這種情況,提示使用者進行確認是一種普遍的做法。本篇文章會示範如何在 React Native 中使用 Modal 來做到這一點。

React Native 的 Modal

React Native 有提供 Modal 元件,為開發者提供了一種簡單且高度可自定義的方式來展示視覺上突出的資訊給使用者。它的設計方式使其內容層次化地覆蓋在應用的主要內容上,方便使用者進行操作。

使用方式非常簡單,只需導入 Modal 後,使用它將你想要展示的內容以子層的方式包覆起來即可,以下是基本的屬性介紹還有範例。

  • visible: 這是最基本的屬性,用於控制 Modal 是否顯示。當 visible 設置為 true 時,Modal 會顯示,否則它會隱藏。

  • animationType: 這個屬性控制 Modal 顯示和消失的動畫類型。它可以是以下值之一:'slide', 'fade' 或 'none'。例如,設置為 'slide' 會使 Modal 從底部滑入和滑出。

  • transparent: 決定 Modal 背景是否透明。當設置為 true 時,你可以看到 Modal 以下的內容,這通常與半透明的遮罩層一起使用,為 Modal 創建模糊或半透明的背景效果。

  • onRequestClose: 主要是一個關閉 Modal 所執行的操作。

這是一個簡單的 Modal 使用範例,包括了上述的一些屬性:

<Modal
  animationType="slide"
  transparent={true}
  visible={state.modalVisible}
  onRequestClose={() => {
    setState({ modalVisible: false });
  }}
>
  {/* Modal 的內容 */}
</Modal>

在 context store 加入 modal 顯示的狀態與其控制方法

我們的目標是使待辦事項在刪除之前彈出確認框。首先,需要在 context store 中加入 Modal 的顯示狀態和其控制方法。

// src/store/index.js
const initialState = {
  inputText: '',
  todos: [],
  modalVisible: {
    confirm: false
  },
  chooseId: null
}

先加入 modalVisiblechooseId 兩個新的 state 屬性。其中:

  • modalVisible: 決定哪個 Modal 是否應該顯示。
  • chooseId: 選擇刪除的待辦事項 ID。

還要加入兩個新的 action,分別為 SET_CHOOSE_IDSET_MODAL_VISIBLE,用於更新這些狀態。

case 'SET_CHOOSE_ID':
      return {
        ...state,
        chooseId: action.payload
      }
case 'SET_MODAL_VISIBLE':
      return {
        ...state,
        modalVisible: {
          ...state.modalVisible,
          [action.payload.name]: action.payload.visible
        }
}

新增 ConfirmModal 元件

接下來,我們將建立一個新的元件 ConfirmModal,這個元件將負責展示 Modal 和其內容。主要提供了使用者取消或確認操作的按鈕,以及一段提示文字。

// src/components/ConfirmModal.js
import { useContext } from 'react'
import { Modal, View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import { Store } from '../store'

const ConfirmModal = () => {
  const { state, dispatch } = useContext(Store)
  const { modalVisible, chooseId } = state

  const closeModel = () => {
    dispatch({
      type: 'SET_MODAL_VISIBLE',
      payload: { name: 'confirm', visible: false }
    })
  }

  const handleDeleteItem = () => {
    dispatch({ type: 'DELETE_ITEM', payload: chooseId })
    closeModel()
  }

  return (
    <View style={styles.container}>
      <Modal
        animationType='fade'
        transparent={true}
        visible={modalVisible.confirm}
        onRequestClose={closeModel}
      >
        <View style={styles.container}>
          <View style={styles.modalWrap}>
            <Text style={styles.title}>確定要刪除嗎?</Text>
            <View style={styles.buttons}>
              <TouchableOpacity
                onPress={closeModel}
                style={[styles.button, { backgroundColor: '#f66162' }]}
              >
                <Text style={{ color: '#fff' }}>取消</Text>
              </TouchableOpacity>
              <TouchableOpacity
                onPress={handleDeleteItem}
                style={[styles.button, { backgroundColor: '#a1f64c' }]}
              >
                <Text>確定</Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>
    </View>
  )
}

export default ConfirmModal

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(0,0,0,0.5)'
  },
  modalWrap: {
    paddingHorizontal: 40,
    paddingTop: 40,
    paddingBottom: 20,
    borderRadius: 10,
    backgroundColor: '#fff'
  },
  title: {
    fontSize: 20,
    fontWeight: 500,
    color: '#333'
  },
  buttons: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    marginTop: 20
  },
  button: {
    padding: 10,
    borderRadius: 5
  }
})

上面的 ConfirmModal 元件的範例,當使用者確定要刪除待辦事項時,它將觸發 handleDeleteItem,並關閉 Modal

然後放到 App.js 中,就可以等待被呼叫並顯示了。

import ConfirmModal from './src/components/ConfirmModal'

export default function App() {
  return (
    <StoreProvider>
      <RootSiblingParent>
        <SafeAreaView style={styles.container}>
          <Head />
          <List />
          <ConfirmModal />
          <StatusBar style='auto' />
        </SafeAreaView>
      </RootSiblingParent>
    </StoreProvider>
  )
}

在 List 控制 ConfirmModal

為了使待辦事項可以被刪除,我們需要在 List 元件中加入控制 ConfirmModal 的邏輯。

// src/components/List.js
const List = () => {
  // 省略

  const handleConfirmDelete = (id) => {
    dispatch({ type: 'SET_CHOOSE_ID', payload: id })
    dispatch({ type: 'SET_MODAL_VISIBLE', payload: { name: 'confirm', visible: true }})
  }

  const renderItem = ({ item }) => (
    <Item
      item={item}
      onToggleItem={() => handleToggleItem(item.id)}
      onConfirmDelete={() => handleConfirmDelete(item.id)}
    />
  )

  // 省略
}

const Item = ({ item, onToggleItem, onConfirmDelete }) => (
  <View style={styles.item}>
    // 省略
    <TouchableOpacity onPress={onConfirmDelete}>
      <MaterialCommunityIcons name='delete-circle' size={24} color='#ED6070' />
    </TouchableOpacity>
  </View>
)

當使用者點擊某一項待辦事項的刪除按鈕時,將觸發 handleConfirmDelete,將設置所選待辦事項的 ID,然後使確認刪除的 Modal 顯示。

Modal

總結

今天在待辦事項 App 中加入了 Modal 提示功能,以增強使用者體驗,並防止誤刪。通過這種方式,不僅提供了更安全的操作環境,也讓 App 更加完整。

接下來將繼續深入探討如何使用 Modal 來編輯待辦事項,這將使我們的 App 功能更加完善,為使用者提供更多功能。


上一篇
Day 11 - 使用 Expo 的 Icons 來增加用戶體驗
下一篇
Day 13 - 使用 Modal 編輯待辦事項
系列文
掌握 React Native 與 Expo:30天雙打,新手也能精通跨平台開發!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言