[Redux] Redux: Extracting Container Components -- AddTodo
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的更多相关文章
- [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] Extracting Container Components -- VisibleTodoList
Code to be refacted: const TodoList = ({ todos, onTodoClick }) => ( <ul> {todos.map(todo =& ...
- [Redux] Extracting Presentational Components -- AddTodo
The code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { ...
- [React] 11 - Redux: redux
Ref: Redux中文文档 Ref: React 讀書會 - B團 - Level 19 Redux 深入淺出 Ref: React+Redux 分享會 Ruan Yifeng, Redux 架构: ...
- Presentational and Container Components
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 There’s a simple pattern I fi ...
- Flux --> Redux --> Redux React 入门
本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...
- [Redux] redux的概述
redux 的概述 随着 javascript 单页应用的不断发展,javascript 需要管理比以往都要多的状态,管理不断变化的 state 非常困难,数据流动不断变的模糊不可预测,代码的开发与维 ...
- Flux --> Redux --> Redux React 基础实例教程
本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推 ...
随机推荐
- Nested Class Templates
Templates can be defined within classes or class templates, in which case they are referred to as ...
- UDP C/S编程
UDP C/S编程的步骤如下图所示与TCP C/S通信的区别在于:服务端没有设置监听和等待连接的过程.客户端没有连接服务端的过程.基于UDP的通信时不可靠地,面向无连接的,发送的数据无法确切知道对方收 ...
- 如何解决svn图标不显示呢?
svn图标不显示解决 确保设置正确: 右键->TortoiseSVN->setting->Icon Overlays->Status cache->default/She ...
- ContextLoaderListener初始化的前后文和DispatcherServlet初始化的上下文关系
ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的,不管是使用什么表现层技术,一般如DAO层.Service层Bean: DispatcherServlet ...
- 模块计算机类型“X64”与目标计算机类型“x86”冲突
问题描述:在X64 平台上开发dll 文件,在生成dll时Vs 2010 出现如下错误 :"fatal error LNK1112: 模块计算机类型"X64"与目标计算机 ...
- Protobuf实现Android Socket通讯开发教程
本节为您介绍Protobuf实现Android Socket通讯开发教程,因此,我们需要先了理一下protobuf 是什么? Protocol buffers是一种编码方法构造的一种有效而可扩展的格式 ...
- 开发日志_Jan.9
今天主要工作为修改昨天的碰撞引擎不符合预期的部分. 经过了昨天的工作,碰撞算法已经初见雏形.但是主要有两个问题: 碰撞反弹的方向与预期不符合 碰撞后球与机器人存在一个"黏在一起"的 ...
- 1:scrapy框架原理与环境搭设
1:原理图: (*此图来自网络) 2:开发过程: 1)编写items.py,确定要抓取的关键字段名称 2)编写spider,确定发送request的形式以及对于response的处理 3)编写pipe ...
- Image控件的简单使用示例1
Image控件加载图片包括加载动态图片,加载静态图片两种方式.一.加载动态图片通过生成一个BitmapImage,创建该对象后,赋给Image的Source即可.加载的形式: 示例1 BitmapIm ...
- 如何获取外网Ip呢, 终于找到方法了
临时更换网址:http://20140507.ip138.com/ic.asp 这个网址能同时获取ip和城市名字 上面的网址如何来的呢,其实很简单,随便打开一个获取Ip的网站,比如http://www ...