【前言】
呼~~終於進行到一半了(灑花!越來越不知道前言要寫什麼來湊字數了XD
【正文】
在這次的範例,我們要利用redux與react再次做一個to do list(其實是我懶得再想範例)。由於redux其實是可以獨立使用,也就是react本身是沒有redux這個套件,所以我們一開始要在我們的專案底下輸入npm install --save react-redux
安裝redux哦。
再來是redux中的react還有兩個名詞:Presentational Component和Container Component,這兩個又是什麼阿?下面來自redux官網的表格可以解釋這兩個的差別:
基本上Presental Component主要是UI的顯示,而Container Component主要的功能就是與redux中的store做連結的。因此,根據上表的對於兩個的特性,我們可以對這個to do list大致分為:
也就是說,TodoList
組件的內容會透過VisibleTodoList
對於redux中的store監聽的state,將最新的state狀態回傳,Link
與FilterLink
亦然。
import React from 'react';
// prop-type:變數型別定義
import PropTypes from 'prop-types';
import Todo from './Todo';
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{/* 根據todos去map出來Todo Component */}
{todos.map((todo, index) => (
<Todo key={index} {...todo} onClick={() => onTodoClick(index)} />
))}
</ul>
);
TodoList.propTypes = {
// todos是個array,裡面存的是帶數字的id屬性、布林的completed屬性、字串的text屬性的物件
todos: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired,
}).isRequired,
).isRequired,
// onTodoClick是個函式
onTodoClick: PropTypes.func.isRequired,
};
export default TodoList;
Todos和onTodoClick都是由
VisibleTodoList
傳遞來的
import React from 'react';
import PropTypes from 'prop-types';
const Todo = ({ onClick, completed, text }) => (
<li
onClick={onClick}
// Todo Item的style
style={ {
textDecoration: completed ? 'line-through' : 'none'
}}
>
{text}
</li>
);
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired,
};
export default Todo;
import React from 'react';
import PropTypes from 'prop-types';
class Link extends React.Component {
onclick = (e) => {
e.preventDefault();
const { onClick } = this.props;
onClick();
}
render() {
const { active, children } = this.props;
if (active) {
return <span>{children}</span>
}
return (
<a href="#" onClick={this.onclick}>
{children}
</a>
)
}
}
Link.propTypes = {
active: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired,
};
export default Link;
onClick、active是由
FilterLink
傳遞來的
import React from 'react';
import FilterLink from '../containers/FilterLink';
import { VisibilityFilters } from '../../actions';
const Footer = () => (
<div>
Show:
{' '}
<FilterLink filter={VisibilityFilters.SHOW_ALL}>
All
</FilterLink>
{', '}
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>
Active
</FilterLink>
{', '}
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>
Completed
</FilterLink>
</div>
);
export default Footer;
import React from 'react';
import Footer from './Footer';
import AddTodo from '../containers/AddTodo';
import VisibleTodoList from '../containers/VisibleTodoList';
const App = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
)
export default App;
今天我們先把Presentational Component的部分先寫完,明天來寫Container Component吧!