Code to be refactored:

const AddTodo = ({
onAddClick
}) => {
let input; return (
<div>
<input ref={node => {
input = node;
}} />
<button onClick={() => {
onAddClick(input.value);
input.value = '';
}}>
Add Todo
</button>
</div>
);
}

Finally, in the previous lesson, I made app ToDo a presentational component, but I'm going to backtrack on this now. I will copy-paste the dispatch call back in line into the onClick handler inside the component because there isn't really a lot of presentation or behavior here.

It's easier to keep them together until we figure out how to split the presentation. For example, if in the future, we're going to have something like a form component, we may split it, but for now we'll keep them together.

const AddTodo = ({
onAddClick
}) => {
let input; return (
<div>
<input ref={node => {
input = node;
}} />
<button onClick={() => {
store.dispatch({
type: 'ADD_TODO',
id: nextTodoId++,
text: input.value
});
input.value = '';
}}>
Add Todo
</button>
</div>
);
};

---------------------------

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={() => {
store.dispatch({
type: 'ADD_TODO',
id: nextTodoId++,
text: 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 />
<VisibleTodoList />
<Footer />
</div>
); const render = () => {
ReactDOM.render(
<TodoApp
{...store.getState()}
/>,
document.getElementById('root')
);
}; store.subscribe(render);
render();

[Redux] Redux: Extracting Container Components -- AddTodo的更多相关文章

  1. [Redux] Extracting Container Components (FilterLink)

    Learn how to avoid the boilerplate of passing the props down the intermediate components by introduc ...

  2. [Redux] Extracting Container Components -- Complete

    Clean TodoApp Component, it doesn't need to receive any props from the top level component: const To ...

  3. [Redux] Extracting Container Components -- VisibleTodoList

    Code to be refacted: const TodoList = ({ todos, onTodoClick }) => ( <ul> {todos.map(todo =& ...

  4. [Redux] Extracting Presentational Components -- AddTodo

    The code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { ...

  5. [React] 11 - Redux: redux

    Ref: Redux中文文档 Ref: React 讀書會 - B團 - Level 19 Redux 深入淺出 Ref: React+Redux 分享會 Ruan Yifeng, Redux 架构: ...

  6. Presentational and Container Components

    https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 There’s a simple pattern I fi ...

  7. Flux --> Redux --> Redux React 入门

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

  8. [Redux] redux的概述

    redux 的概述 随着 javascript 单页应用的不断发展,javascript 需要管理比以往都要多的状态,管理不断变化的 state 非常困难,数据流动不断变的模糊不可预测,代码的开发与维 ...

  9. Flux --> Redux --> Redux React 基础实例教程

    本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...

随机推荐

  1. Java 之 StringTokenizer

    class StringTokenizer Object to: break a string into tokens. Contructs StringTokenizer(String str)   ...

  2. Linux命令之用户与组管理

    介绍 Linux操作系统中,任何文件都归属某一特定的用户,而任何用户都隶属至少一个用户组.用户是否有权限对某文件进行访问.读写以及执行,受到系统严格约束的正式这种清晰.严谨的用户与用户组管理系统.在很 ...

  3. vb的LINQ实现

    vb实现LINQ非常简单的例子: Dim numbers() As Integer = {1, 2, 3, 4, 5, 6, 7} Dim allNumbers = From number In nu ...

  4. 解决手机浏览器和微信中select中border:none;无用和去掉小三角

    设置select的边框为none:在PC端是没有问题的,但是放到手机浏览器和微信里上还是会出现边框 解决办法: appearance:none; -moz-appearance:none; /* Fi ...

  5. Flexbox属性查询列表

    1.任何一个flexbox布局的第一步是需要创建一个flex容器.为此给元素设置display属性的值为flex.在Safari浏览器中,你依然需要添加前缀-webkit. .flexcontaine ...

  6. Ubuntu下安装android studio的时候,无法进入图形界面--/usr/lib/jdk1.8.0_60/jre/lib/i386/libawt_xawt.so: libXtst.so.6: 无法打开共享对象文件: 没有那个文件或目录

    详细错误描述: java.lang.reflect.InvocationTargetException    at sun.reflect.NativeMethodAccessorImpl.invok ...

  7. 22 java常用方法

    /** * 通过正则获取该目录下满足条件的所有目录 * @param luceneFilePathRegular 正则目录,如/user/solrindex/正则表达式 * @return 满足正则表 ...

  8. 安全性良好的operator=操作,和新的new方法(针对深度复制的情况)

    class B { }; class A { public: A& operator=(const A& a) { B* temp = b; //这里解决重复赋值的方法是用temp指向 ...

  9. windows启动、停止和重新启动Apache服务

    启动.停止和重新启动Apache服务(1) 在Windows操作系统中,Apache一般以服务的方式运行.在安装Apache时,如果你选择了“for all users”,Apache就会自动安装为一 ...

  10. Guava API学习之Multimap

    相信大家对Java中的Map类及其之类有大致的了解,Map类是以键值对的形式来存储元素(Key->Value),但是熟悉Map的人都知 道,Map中存储的Key是唯一的.什么意思呢?就是假如我们 ...