[Redux] Extracting Container Components -- VisibleTodoList
Code to be refacted:
- const TodoList = ({
- todos,
- onTodoClick
- }) => (
- <ul>
- {todos.map(todo =>
- <Todo
- key={todo.id}
- {...todo}
- onClick={() => onTodoClick(todo.id)}
- />
- )}
- </ul>
- );
- let nextTodoId = 0;
- const TodoApp = ({
- todos,
- visibilityFilter
- }) => (
- <div>
- ...
- ...
- <TodoList
- todos={
- getVisibleTodos(
- todos,
- visibilityFilter
- )
- }
- onTodoClick={id =>
- store.dispatch({
- type: 'TOGGLE_TODO',
- id
- })
- }
- />
- ....
- </div>
- );
Currently we pass the 'todos' and 'onTodoClick' from top container component 'TodoApp', all the way down to the 'Todo' component.
So we want simplfy 'TodoList' Component in TodoApp, create a new container component 'VisibleTodoList'.
In TodoApp:
- const TodoApp = ({
- todos,
- visibilityFilter
- }) => (
- <div>
- <AddTodo
- onAddClick={text =>
- store.dispatch({
- type: 'ADD_TODO',
- id: nextTodoId++,
- text
- })
- }
- />
- <VisibleTodoList />
- <Footer />
- </div>
- );
VisibleTodoList:
- class VisibleTodoList extends Component {
- componentDidMount() {
- this.unsubscribe = store.subscribe(() =>
- this.forceUpdate()
- );
- }
- componentWillUnmount() {
- this.unsubscribe();
- }
- render() {
- const props = this.props;
- const state = store.getState();
- return (
- <TodoList
- todos={
- getVisibleTodos(
- state.todos,
- state.visibilityFilter
- )
- }
- onTodoClick={id =>
- store.dispatch({
- type: 'TOGGLE_TODO',
- id
- })
- }
- />
- );
- }
- }
----------------
Code:
- const todo = (state, action) => {
- switch (action.type) {
- case 'ADD_TODO':
- return {
- id: action.id,
- text: action.text,
- completed: false
- };
- case 'TOGGLE_TODO':
- if (state.id !== action.id) {
- return state;
- }
- return {
- ...state,
- completed: !state.completed
- };
- default:
- return state;
- }
- };
- const todos = (state = [], action) => {
- switch (action.type) {
- case 'ADD_TODO':
- return [
- ...state,
- todo(undefined, action)
- ];
- case 'TOGGLE_TODO':
- return state.map(t =>
- todo(t, action)
- );
- default:
- return state;
- }
- };
- const visibilityFilter = (
- state = 'SHOW_ALL',
- action
- ) => {
- switch (action.type) {
- case 'SET_VISIBILITY_FILTER':
- return action.filter;
- default:
- return state;
- }
- };
- const { combineReducers } = Redux;
- const todoApp = combineReducers({
- todos,
- visibilityFilter
- });
- const { createStore } = Redux;
- const store = createStore(todoApp);
- const { Component } = React;
- const Link = ({
- active,
- children,
- onClick
- }) => {
- if (active) {
- return <span>{children}</span>;
- }
- return (
- <a href='#'
- onClick={e => {
- e.preventDefault();
- onClick();
- }}
- >
- {children}
- </a>
- );
- };
- class FilterLink extends Component {
- componentDidMount() {
- this.unsubscribe = store.subscribe(() =>
- this.forceUpdate()
- );
- }
- componentWillUnmount() {
- this.unsubscribe();
- }
- render() {
- const props = this.props;
- const state = store.getState();
- return (
- <Link
- active={
- props.filter ===
- state.visibilityFilter
- }
- onClick={() =>
- store.dispatch({
- type: 'SET_VISIBILITY_FILTER',
- filter: props.filter
- })
- }
- >
- {props.children}
- </Link>
- );
- }
- }
- const Footer = () => (
- <p>
- Show:
- {' '}
- <FilterLink
- filter='SHOW_ALL'
- >
- All
- </FilterLink>
- {', '}
- <FilterLink
- filter='SHOW_ACTIVE'
- >
- Active
- </FilterLink>
- {', '}
- <FilterLink
- filter='SHOW_COMPLETED'
- >
- Completed
- </FilterLink>
- </p>
- );
- const Todo = ({
- onClick,
- completed,
- text
- }) => (
- <li
- onClick={onClick}
- style={{
- textDecoration:
- completed ?
- 'line-through' :
- 'none'
- }}
- >
- {text}
- </li>
- );
- const TodoList = ({
- todos,
- onTodoClick
- }) => (
- <ul>
- {todos.map(todo =>
- <Todo
- key={todo.id}
- {...todo}
- onClick={() => onTodoClick(todo.id)}
- />
- )}
- </ul>
- );
- const AddTodo = ({
- onAddClick
- }) => {
- let input;
- return (
- <div>
- <input ref={node => {
- input = node;
- }} />
- <button onClick={() => {
- onAddClick(input.value);
- input.value = '';
- }}>
- Add Todo
- </button>
- </div>
- );
- };
- 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
- );
- }
- }
- class VisibleTodoList extends Component {
- componentDidMount() {
- this.unsubscribe = store.subscribe(() =>
- this.forceUpdate()
- );
- }
- componentWillUnmount() {
- this.unsubscribe();
- }
- render() {
- const props = this.props;
- const state = store.getState();
- return (
- <TodoList
- todos={
- getVisibleTodos(
- state.todos,
- state.visibilityFilter
- )
- }
- onTodoClick={id =>
- store.dispatch({
- type: 'TOGGLE_TODO',
- id
- })
- }
- />
- );
- }
- }
- let nextTodoId = 0;
- const TodoApp = ({
- todos,
- visibilityFilter
- }) => (
- <div>
- <AddTodo
- onAddClick={text =>
- store.dispatch({
- type: 'ADD_TODO',
- id: nextTodoId++,
- text
- })
- }
- />
- <VisibleTodoList />
- <Footer />
- </div>
- );
- const render = () => {
- ReactDOM.render(
- <TodoApp
- {...store.getState()}
- />,
- document.getElementById('root')
- );
- };
- store.subscribe(render);
- render();
[Redux] Extracting Container Components -- VisibleTodoList的更多相关文章
- [Redux] Extracting Container Components (FilterLink)
Learn how to avoid the boilerplate of passing the props down the intermediate components by introduc ...
- [Redux] Extracting Container Components -- Complete
Clean TodoApp Component, it doesn't need to receive any props from the top level component: const To ...
- [Redux] Redux: Extracting Container Components -- AddTodo
Code to be refactored: const AddTodo = ({ onAddClick }) => { let input; return ( <div> < ...
- [Redux] Extracting Presentational Components -- AddTodo
The code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { ...
- [Redux] Extracting Presentational Components -- Footer, FilterLink
Code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { todo ...
- [Redux] Extracting Presentational Components -- TodoApp
Finally, I just noticed that the to-do app component doesn't actually have to be a class. I can turn ...
- [Redux] Extracting Presentational Components -- Todo, TodoList
Code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { todo ...
- Presentational and Container Components
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 There’s a simple pattern I fi ...
- (翻译)React Container Components
原文:Container Components Container Components 在 React 模式上对我的代码有最深远影响的一个模式叫 container component 模式. 在 ...
随机推荐
- win32线程池代码(WinApi/C++)
win32线程池代码(WinApi/C++) 健壮, 高效,易用,易于扩, 可用于任何C++编译器 //说明, 这段代码我用了很久, 我删除了自动调整规模的代码(因为他还不成熟)/********** ...
- Java基础知识强化40:StringBuffer类之StringBuffer的替换功能
1. StringBuffer的替换功能: public StringBuffer replace(int start, int end, String str): 2. 案例演示: p ...
- 自定义ViewGroup 流式布局
使用 public class MainActivity extends Activity { @Override protected void onCreate(Bundle sav ...
- ComboGrid( 数据表格下拉框)
一. 加载方式//class 加载方式<select id="box" class="easyui-combogrid" name="dept& ...
- django: form fileupload - 2
继续介绍文件上传的第二种形式和第三种形式. ------------------------------------------------------------- 第二种形式较简单,直接用 DB ...
- 页面传值中get和post区别
get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应. post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到 ...
- angular 指令 要点解析
指令可以删繁就简前端的js代码,杜绝重复的js代码和html代码. 下面就对指令的重要属性进行罗列 一.restrict = 'AECM' 分别指该指令标识位于 attribute属性: < ...
- C++拾遗(二)关于变量
符号常量——预处理方式 例如: #define ZERO 0 会替换程序中所有的ZERO为0,在那些设计为用于C和C++的头文件中,必须使用#define来定义符号常量. 无符号类型 unsigned ...
- uva 10609 - Fractal
题目大意:给出A,B两个点的坐标,以及T,每次找到A.B的四等分点C,D,然后以AB/2为边长,C,D为顶点,构建一个等边三角形,E为另外一个顶点,然后再对C,E:E,D做同样的操作,直到构建的等边三 ...
- 学习心得记录:[一]sql安装与配置
时间:2015年9月13日 02:43:09 科目:mysql的安装 笔记: 准备: 1.首先下载解压版的mysql 2.将下载好的文件放到c:\Program Files\MYSQL下(mysql文 ...