上一篇中我們已經將AddTodo建立好並且確認Reducer會產生新的state,接下來要建立將Todo物件顯示在UI的組件,由於TodoList只負責渲染畫面並且接收到的數據均是來自props,所以它是屬於Presentational Component,而VisibleTodoList是要進行篩選Filter的邏輯處理,所以歸類為Container Component。
藉由mapDispatchToProps會在state發生改變(新增新的todo物件)時會自動調用,將新增的todos Array帶入getVisibleTodos function中進行Filter的邏輯判斷,以Filter的型態決定顯示那些Todo物件,而篩選過後的todos會透過connect傳遞給TodoList進行UI選染。
import { connect } from "react-redux";
import { toggleTodo } from "../Store/Action/Action";
import TodoList from "../Presentational Component/TodoList";
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
default:
break;
}
};
//當State更新後自動調用
const mapStateToProps = (state) => {
/*將State中的todo傳入getVisibleTodos function進行篩選Filter邏輯判斷,
return判斷結果給todos中*/
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
};
//將onTodoClick傳遞給Presentational Components作為callback
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
//篩選過後的todos與callback藉由connect傳遞給TodoList
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
從VisibleTodoList進行邏輯判斷後,將篩選玩的Todos與callback function藉由connect傳遞給TodoList,TodoList再將收到的props進行UI選染。
import React from "react";
import Todo from "./Todo";
const TodoList = (props) => {
console.log(props) //藉由console查看傳遞到TodoList的props內容
return(
<ul>
{
props.todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={()=> props.onTodoClick(todo.id)}
/>
)
}
</ul>
)
};
export default TodoList;
TodoList的props是篩選過後的Todos與onClick callback function
import React from "react";
const Todo = (props) => {
return(
<li
onClick={props.onClick}
style={{
textDecoration: props.completed ? 'line-through' : 'none'
}}
>
{props.text}
</li>
)
};
export default Todo;
參考資料 :
從Redux 的作者學習它