Day 18 To Do List - 加入逻辑 1

第 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>

那结果会是:

这样就看到,我们的资料新增已经跟画面连动了


<<:  Day18# Leetcode TwoSum

>>:  IOS、Python自学心得30天 Day-30 简单辨识范例

Day 8 超多的范例?怎麽办呢?

该文章同步发布於:我的部落格 昨天我们做了一个关於汉堡种类的测试,但真正的测试怎麽可能这麽少呢! ...

DAY 1『 Xcode 如何建专案 』

先到以下网址下载最新版的 Xcode 软件 https://developer.apple.com/...

[2021铁人赛 Day15] General Skills 12

引言 昨天使用到 strings 与 grep 这两个工具, 主要是用来寻找一堆资料中的字串的。 ...

Day 20-制作购物车系统之建立Routes&Controller

购物车後端的部分终於要结束啦~ 以下内容有参考教学影片,底下有附网址。 (内容包括我的不专业解说分析...

Day33. 迭代器模式

本文同步更新於blog Iterator Pattern 提供一种方法顺序访问一个聚合对象中的各个...