iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Modern Web

React Native & Redux 初步探討系列 第 18

Day 18 To Do List - 加入邏輯 1

  • 分享至 

  • xImage
  •  

第 18 天~

昨天已經把畫面給佈置好了

https://ithelp.ithome.com.tw/upload/images/20211003/20112878TcAYB8AnMx.png

有了畫面,但是沒有任何的邏輯,所以現在任何操作其實都不會有相關的邏輯

今天我們來把相關的邏輯給建立起來,

react 是以資料邏輯來帶動畫面變化的,

所以必須建立相對應的資料以及邏輯,

來達成我們預期的變化,

來看看我們的需求:

  • 新增代辦事項
  • 完成代辦事項
  • 搜尋
  • 全部完成
  • 代辦事項列表

所以我們可以翻譯成:

  • 新增項目
  • 改變項目狀態
  • filter 列表
  • 改變列表狀態
  • 顯示列表

從上面的需求看,

顯示列表

我們必須有個地方來保存列表資料,

並且跟著畫面做連動

在這裡我們些把 App component 轉成 class component

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <SafeAreaView style={styles.root}>
        <View style={styles.header}>
          <Text style={styles.title}>My To Do List</Text>
          <TextInput style={styles.input} />
          <View style={styles.buttonGroup}>
            <TouchableOpacity style={styles.button}>
              <Text style={styles.buttonText}>Add</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.button}>
              <Text style={styles.buttonText}>Search</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.button}>
              <Text style={styles.buttonText}>Complete All</Text>
            </TouchableOpacity>
          </View>
        </View>
        <FlatList
          data={list}
          renderItem={({ item, index, separators }) => {
            const backgroundColorStyle =
              index % 2 === 0 ? styles.itemEven : styles.itemOdd;
            return (
              <TouchableOpacity
                style={[styles.item, backgroundColorStyle, styles.itemDone]}>
                <View style={[styles.tickArea, styles.tick]}></View>
                <Text style={[styles.itemText, styles.doneText]}>
                  {item.text}
                </Text>
              </TouchableOpacity>
            );
          }}
          keyExtractor={(item) => item.id}
        />
      </SafeAreaView>
    );
  }
}

並在 state 設定 list 參數,用來保存我們的 todoList 內容

constructor(props) {
  super(props);
  this.state = {
    list:[]
  }
}

並把 list 帶入到 renderFlatList data

render() {
  const {list} = this.state;
  return (
    <SafeAreaView style={styles.root}>
      <View style={styles.header}>
        <Text style={styles.title}>My To Do List</Text>
        <TextInput style={styles.input} />
        <View style={styles.buttonGroup}>
          <TouchableOpacity style={styles.button}>
            <Text style={styles.buttonText}>Add</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button}>
            <Text style={styles.buttonText}>Search</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button}>
            <Text style={styles.buttonText}>Complete All</Text>
          </TouchableOpacity>
        </View>
      </View>
      <FlatList
        data={list}
        renderItem={({item, index, separators}) => {
          const backgroundColorStyle =
            index % 2 === 0 ? styles.itemEven : styles.itemOdd;
          return (
            <TouchableOpacity
              style={[styles.item, backgroundColorStyle, styles.itemDone]}>
              <View style={[styles.tickArea, styles.tick]}></View>
              <Text style={[styles.itemText, styles.doneText]}>
                {item.text}
              </Text>
            </TouchableOpacity>
          );
        }}
        keyExtractor={item => item.id}
      />
    </SafeAreaView>
  );
}

這時候畫面會是:

這樣代表我們的資料跟畫面已經初步產生連動了,

新增列表項目

接下來我們要可以把在 input 輸入的內容新增到 list

首先我們新增 inputValue state 來保存 input 的內容:

this.state = {
  inputValue: '',
  list: [],
};

inputValue 帶入到 TextInput component

const { list, inputValue } = this.state;
<TextInput style={styles.input} value={inputValue} />;

TextInput component 設定 onChangeText

onInputChange = (text) => {
  this.setState(() => {
    return {
      inputValue: text,
    };
  });
};

<TextInput
  style={styles.input}
  value={inputValue}
  onChangeText={this.onInputChange}
/>;

這樣,與 input 的連動就告一段落了,

再來, 我們來定義 todo item 的格式,

來看看 item 的需求:

  • 要有 text 來敘述做什麼
  • 要可以有 status 判斷 done or not done
  • 要有 id 方便之後好搜尋,那這必須要有唯一性,所以用 timestamp 來當做 id 好了

所以我們格式大約是,

const item ={
  id: 0
  text: '',
  status: ''// done or not done
}

所以我們建立一個 function 專門控管 item 新增

createToDoItem = () => {
  const { inputValue, list } = this.state;

  const item = {
    id: new Date().getTime(),
    text: inputValue,
    status: 'not Done',
  };

  const newList = [...list, item];

  this.setState(() => {
    return {
      inputValue: '',
      list: newList,
    };
  });
};

像上面的程式碼,

我們先把 state 取出 inputValuelist,

在把 需要新增的 item 放入到 list

然後記得把 inputValue , 不然 input 會留住已新增的項目

最後,用 setState 來更新,

最後把 createToDoItem 放入到 Add 的 TouchableOpacity componentonPress

<TouchableOpacity style={styles.button} onPress={this.createToDoItem}>
  <Text style={styles.buttonText}>Add</Text>
</TouchableOpacity>

那結果會是:

這樣就看到,我們的資料新增已經跟畫面連動了


上一篇
Day 17 To Do List - 切版 2
下一篇
Day 19 To Do List - 加入邏輯 2
系列文
React Native & Redux 初步探討33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言