iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0
Mobile Development

單人開發者之路:React Native 與 Expo 帶你從開發到上架系列 第 6

Day 6 - React Native 基礎知識(二) - Props、State

  • 分享至 

  • xImage
  •  

接續上篇components、JSX介紹後
React官方描述的核心概念還有下面兩項

  • props
  • state

這兩項核心會介紹比較長
因為這是後續開發使用者體驗(UX)時的核心項目

Props

官方說明:https://reactnative.dev/docs/props.html

Props 用於表示 React Native Components接收的屬性或參數
也是A元件要給B元件使用並互動時,Props作為A、B元件的重要橋梁
不是代表所有的參數跟屬性都要命名為Props

這邊直接修改App.js做講解

  1. 新增另一個Component MyText
  2. 屬性名稱取為{ TextContent } React規定要使用屬性Props時,必須要加大括弧
  3. 直接將TextContent這個屬性的內容,丟到元件
function MyText({ TextContent }) {
  return <Text>{TextContent}</Text>;
}
export default function App() {
  return (
    <View>
      <MyText TextContent="Hello" SubTextContent="World" />
    </View>
  );
}

輸出結果:Hello

當然上方寫法不完全是正解
如果屬性(Props)變多時,程式碼勢必變得繁雜

JavaScript非常貼心的提供一項運算式「解構賦值」

解構賦值 (Destructuring assignment) 語法是一種 JavaScript 運算式,可以把陣列或物件中的資料解開擷取成為獨立變數。

引用文字敘述或許複雜了點...同樣的在修改App.js示範「解構賦值」的效果

function MyText(myprops) {
  return (
    <Text>
      {myprops.TextContent} {myprops.SubTextContent}
    </Text>
  );
}
export default function App() {
  return (
    <View>
      <MyText TextContent="Hello" SubTextContent="World" />
    </View>
  );
}

輸出結果:Hello World

這時MyText元件仍只有一個參數myprops
但能同時讀取TextContent、SubTextContent兩個屬性中的值
也是解構賦值最大的特點

建議整個專案的風格挑選一種來實作就好
才能維持程式設計中的可讀性及一致性


State

官方說明:https://reactnative.dev/docs/state

React、React Native有個最主要的特點
在執行 return 渲染畫面之後,想要更新畫面資訊,需透過「狀態(State)更新」
通知React Native,觸發更新這個畫面的資訊
也是最常使用的核心項目

想要更新畫面資訊時
一定要狀態(State)改變,才能更新畫面上資訊

跟以往Html JavaScript不同,可以直接對著元素做文字、樣式改變

State 通常在實務上什麼時候會使用

  • 按下按鈕,更新畫面內容時(文字、樣式、清單)
  • 從後端API取得資料,要帶入到畫面時
  • 其他提供使用者操作功能時

State 如何使用

直接附上一個「計數器加一減一」需求的範例

import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const App = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (

    <View style={styles.container}>
      <Text style={styles.text}>Count: {count}</Text>
      <Button title="Increment" onPress={increment} />
      <Button title="Decrement" onPress={decrement} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 20,
    marginBottom: 10,
  },
});

export default App;

結果如下
Result

程式說明:

  1. useState 是 React Hook 專屬語法,因此程式import的是react,而不是react native

  2. 初始化計數器的狀態 const [count, setCount] = useState(0);
    翻譯成中文就是[狀態變數, 更新函數] = 初始變數(0);

  3. [count, setCount]變數、函數名稱可自行取名
    命名方式要以需求面為主(一眼能看出count是存放計數器的數字)
    這裡也稍微提一下JavaScript慣用命名方式,以便日後維護起來更輕鬆

一般來說,JavaScript 的命名慣例建議使用駝峰式命名法(camelCase)來命名變數、函數和物件屬性。在駝峰式命名法中,第一個單詞的首字母小寫,後面的每個單詞的首字母大寫,而且不使用空格或特殊字元。

  1. <Button> 為React Native按鈕元件
    基本上現有APP一定都需要按鈕,才能觸發元件狀態更新

  2. Increment按鈕觸發了increment function
    執行setCount(count + 1);
    在執行這段時,除了count被+1外
    同時觸發了State的更新機制「狀態改變」
    畫面的Count也從0被加到1

    Decrement減法按鈕同上述做法,會將畫面的count - 1

State 可以存放什麼

可以存放任何 JavaScript 值

  1. 數字:const [count, setCount] = useState(0);
  2. 文字:const [name, setName] = useState("John Doe");
  3. 布林:const [isVisible, setIsVisible] = useState(true);
  4. 物件:const [formData, setFormData] = useState({ username: "", email: "" });
  5. 陣列:const [items, setItems] = useState(["apple", "banana", "cherry"]);

當今天要點一下「更新」按鈕,更新使用者資訊時
useState就會存放物件、而不是數字或其他值

如果 setState 的值沒有變動,還會更新畫面嗎

依上述範例,如果今天在計數器多加一支function

const handleIncrement = () => {
    setCount(1);
};

如果計數器的值已經是1的時候
在點選按鈕觸發handleIncrement
React 會比較新的狀態和之前的狀態,只有在它們不相等時才會觸發重新渲染
這是 React 的性能優化之一,它確保只有在真正需要更新的情況下
才重新渲染Component。


結語:
自身也是傳統Html轉前端框架的初學者
在學習React、React Native的核心技術時
實在非常吃力
建議也多翻閱React Native官網的技術文件
官方親自示範這些核心技術的使用範例
對我這個初學者而言幫助很大

而下一篇開始
將進入真正的專案開發階段
也就是從「前端切版」為出發點
由「從做中學」的角度,一步步帶你完成一個APP專案


上一篇
Day 5 - React Native 基礎知識(一) - Components、JSX
下一篇
Day 7 - 你的APP快速切板選擇 Tailwind CSS
系列文
單人開發者之路:React Native 與 Expo 帶你從開發到上架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言