Day 28 加入 Action

第 28 天 !

倒数 3 天!

当我们道路都打通後,我们要开始想要传什麽资料进去,

首先,我们要确定要放在 redux store 的资料是什麽?

通常,我们会把我们整个专案都会用到的资料放入到 store 里,

所以,我们先把 todoList 的资料移入到 todoReducer

const initState = {
  list: [],
};

export default function todoReducer(state = initState, action) {
  return state;
}

我们会先设定好 initState ,并且把它当作这个 todoReducer state 的初始值,

最後 return ,这样我们就把我们的 todoList 保存在 store 里了

再来我们需要从 mapStateToProps 拿到我们的 todoList

const mapStateToProps = ({ todo }) => {
  return {
    todo,
  };
};

再来导入到 ToDoList Component,

function ToDoList({ todo, changeItemStatus }) {
  const { list } = todo;
  return (
    <FlatList
      data={list}
      renderItem={({ item, index, separators }) => {
        const isEven = index % 2 === 0;
        const isDone = item.status === 'done';
        return (
          <ToDoItem
            isEven={isEven}
            isDone={isDone}
            text={item.text}
            onPress={changeItemStatus}
          />
        );
      }}
      keyExtractor={(item) => item.id}
    />
  );
}

这样,我们就已经从 store 取出 todoListcomponent

当我们已经取得资料後,我们需要去设定 action ,让我们可以去操控我们的资料,

action 都是根据需求去设定的,

针对 todoList 需求如下:

  • 新增
  • 修改状态
  • 全部完成

我们在根目录建立 actions 资料夹,并在底下建立两个档案,

  • types.js
  • creators.js

types 是专门放置 action type , creators 就是放置 action creator

  • types.js
export const INSERT_TODO = 'INSERT_TODO';

export const CHANGE_TODO_STATUS = 'CHANGE_TODO_STATUS';

export const ALL_TODO_COMPLETE = 'ALL_TODO_COMPLETE';

action type , 通常会用全部大写的方式表示,内容跟变数名称会是一致的

  • creators.js
import { ALL_TODO_COMPLETE, CHANGE_TODO_STATUS, INSERT_TODO } from './types';

export const insertToDoAction = (payload) => {
  return {
    type: INSERT_TODO,
    payload,
  };
};

export const changeToDoStatusAction = (payload) => {
  return {
    type: CHANGE_TODO_STATUS,
    payload,
  };
};

export const completeAllAction = () => {
  return {
    type: ALL_TODO_COMPLETE,
  };
};

再来,我们到 todoReducer 设定我们的 action 动作,

const initState = {
  list: [],
};

const insertToDo = (state, item) => {
  return {
    ...state,
    list: [...state.list, item],
  };
};

const changeToDoStatus = (state, { id }) => {
  const { list } = state;
  const index = list.findIndex((item) => item.id === id);

  const nowItem = list[index];

  const newStatus = nowItem.status === 'done' ? 'not done' : 'done';

  list[index] = {
    ...nowItem,
    status: newStatus,
  };

  return {
    ...state,
    list: [...list],
  };
};

const allToDoComplete = (state) => {
  return {
    ...state,
    list: state.list.map((item) => {
      return {
        ...item,
        status: 'done',
      };
    }),
  };
};

export default function todoReducer(state = initState, { type, payload }) {
  switch (type) {
    case INSERT_TODO:
      return insertToDo(state, payload);
    case CHANGE_TODO_STATUS:
      return changeToDoStatus(state, payload);
    case ALL_TODO_COMPLETE:
      return allToDoComplete(state);
    default:
      return state;
  }
}

这时候,就把从 App component 的逻辑迁到 todoReducer 里,

我们移入到 Header component

现在来设定 mapDispatchToProps

假如没有什麽特别要设定的,

我们可以直接把 action creator 拿来用就好

const mapDispatchToProps = {
  insertToDoAction,
};

Header componentinsertToDoAction 取代 createToDoItem

onAddButtonPress = () => {
  const { inputValue } = this.state;

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

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

  this.props.insertToDoAction(item);
};

Complete All ButtoncompleteAllAction 取代 handleCompleteAll

<FeatureButton text={'Complete All'} onPress={this.props.completeAllAction} />

再来到 ToDoList component

  • mapDispatchToProps
const mapDispatchToProps = {
  changeToDoStatusAction,
};
  • ToDoItem component
<ToDoItem
  isEven={isEven}
  isDone={isDone}
  text={item.text}
  onPress={() => changeToDoStatusAction(item.id)}
/>

这样就大功告成啦


<<:  Day 29 RSpec 里的 Factories 和 Fixtures

>>:  响应式网站注意细节-30天学会HTML+CSS,制作精美网站

Day 27 - 强化学习 Reinforcement Learning(1)

马可夫决策过程 Markov decision process MDP 在概率论和统计学中,马可夫决...

拿 ml5 来练习 p5.js (二)

介绍 首先介绍什麽是 p5.js, p5.js 是基於 Processing 在浏览器中提供友善的画...

『为什麽我的Wifi这麽慢?』

在一个小办公室里面,如果大家(通常是五人)都坐下来打开笔电,一起用同一个AP无线上网,然後就说出标题...

Day 26: 载入图片

这系列的程序码在 https://github.com/DanSnow/ironman-2020/...

# Day17--那天....我学Wendy跪着读完的OOP

什麽是物件导向? 为什麽需要物件导向? 物件导向重要在什麽地方? 要回答第一个问题前,必须先回答一...