Code to be refactored:

class FilterLink extends Component {
componentDidMount() {
const { store } = this.context;
this.unsubscribe = store.subscribe(() =>
this.forceUpdate()
);
} componentWillUnmount() {
this.unsubscribe();
} render() {
const props = this.props;
const { store } = this.context;
const state = store.getState(); return (
<Link
active={
props.filter ===
state.visibilityFilter
}
onClick={() =>
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: props.filter
})
}
>
{props.children}
</Link>
);
}
}
FilterLink.contextTypes = {
store: React.PropTypes.object
};

First to create mapStateToProps, It is fairly common to use the container props when calculating the child props, so this is why props are passed as a second argument:

const mapStateToLinkProps = (
state,
ownProps
) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}

Second, we need to write mapDispatchToProp function:

const mapDispatchToLinkProps = (
dispatch,
ownProps
) => {
return {
onClick: () => {
dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: ownProps.filter
})
}
}
}

Last, we need to create connect function, point to the Link compoment:

const FilterLink = connect(mapStateToLinkProps, mapDispatchToLinkProps)(Link);

We can now use the filter link container component and specify just the filter, but the underlying link component will have received the calculated active and on-click values.

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

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 { Component } = React; const Link = ({
active,
onClick,
children,
}) => {
if (active) {
return <span>{children}</span>;
} return (
<a href='#'
onClick={e => {
e.preventDefault();
onClick();
}}
>
{children}
</a>
);
}; const { connect } = ReactRedux;
const mapStateToLinkProps = (
state,
ownProps
) => {
return {
active: ownProps.filter === state.visibilityFilter
}
} const mapDispatchToLinkProps = (
dispatch,
ownProps
) => {
return {
onClick: () => {
dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: ownProps.filter
})
}
}
} const FilterLink = connect(mapStateToLinkProps, mapDispatchToLinkProps)(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>
); let nextTodoId = 0;
let AddTodo = ({ dispatch }) => {
let input; return (
<div>
<input ref={node => {
input = node;
}} />
<button onClick={() => {
dispatch({
type: 'ADD_TODO',
id: nextTodoId++,
text: input.value
})
input.value = '';
}}>
Add Todo
</button>
</div>
);
};
AddTodo = connect()(AddTodo); 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
);
}
} const mapStateToTodoListProps = (state) => {
return {
todos: getVisibleTodos(
state.todos,
state.visibilityFilter
)
};
}; const mapDispatchToTodoListProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch({
type: 'TOGGLE_TODO',
id
});
}
};
}; const VisibleTodoList = connect(
mapStateToTodoListProps,
mapDispatchToTodoListProps
)(TodoList); const TodoApp = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
); const { Provider } = ReactRedux;
const { createStore } = Redux; ReactDOM.render(
<Provider store={createStore(todoApp)}>
<TodoApp />
</Provider>,
document.getElementById('root')
);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.4/redux.js"></script>
<script src="https://fb.me/react-0.14.0.js"></script>
<script src="https://fb.me/react-dom-0.14.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.0/react-redux.js"></script>
</head>
<body>
<div id='root'></div>
</body>
</html>

[Redux] Generating Containers with connect() from React Redux (FooterLink)的更多相关文章

  1. [Redux] Generating Containers with connect() from React Redux (VisibleTodoList)

    Learn how to use the that comes with React Redux instead of the hand-rolled implementation from the ...

  2. [Redux] Generating Containers with connect() from React Redux (AddTodo)

    Code to be refacted: const AddTodo = (props, { store }) => { let input; return ( <div> < ...

  3. 使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用

    先看效果图 github地址 github仓库 在线访问 初始化项目 #创建项目 create-react-app applist #如果没有安装create-react-app的话,先安装 npm ...

  4. React Redux Sever Rendering实战

    # React Redux Sever Rendering(Isomorphic JavaScript) ![React Redux Sever Rendering(Isomorphic)入门](ht ...

  5. react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware

    今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...

  6. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  7. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  8. react+redux+generation-modation脚手架添加一个todolist

    当我遇到问题: 要沉着冷静. 要管理好时间. 别被bug或error搞的不高兴,要高兴,又有煅炼思维的机会了. 要思考这是为什么? 要搞清楚问题的本质. 要探究问题,探究数据的流动. TodoList ...

  9. 实例讲解基于 React+Redux 的前端开发流程

    原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...

随机推荐

  1. 文件atime未变问题的研究

    1. atime, ctime 以及mtime 这三个名词属于文件/文件夹的属性,存在于inode数据结构之中. 通过系统调用stat可以获取stat结构,其中包括:atime(accesstime) ...

  2. uva11624 - Fire!

    uva11624 - Fire! 火在蔓延,人在走.火会蔓延,不会熄灭,我们可以确定某个点着火的时间(广搜).对于J来说,要是他走到某点的时间比火蔓延到该点的时间要短,那么他走到该点的时候,火还没蔓延 ...

  3. WebApplication和WebSite的区别

    不同点 1. 创建方式不同 一个是FILE->NEW->PROJECT->ASP.NET WEB APPLICATION 另外一个是 FILE->NEW->WEBSITE ...

  4. NFinal简介

    NFinalWeb框架是基于魔法糖语法思想创建的框架.本框架有两大特点.1.所有框架里最简单易学易配置的.2.所有框架里运行效率最快的. 相关介绍1.运行效率比任何php和java以及.net框架要快 ...

  5. VB短信猫开发包,支持超长短信

    一.短信猫开发包(长短信/异步调用)说明:   短信猫开发包以OCX控件的形式提供,支持Windows平台下常用的开发工具:如VB.VB.net.VC++.Power Builder.C#.DELPH ...

  6. T4模板_根据DB生成实体类

    为了减少重复劳动,可以通过T4读取数据库表结构,生成实体类,用下面的实例测试了一下 1.首先创建一个项目,并添加文本模板: 2.添加 文本模板: 3.向T4文本模板文件添加代码: <#@ tem ...

  7. 1218.3——init自定义

    相当于构造方法,有的时候初始化的时候有一些默认值,还有就是页面加载数据的时机问题,防止加载了页面再填数据 声明: -(instancetype)initWithName:(NSString *)aNa ...

  8. “有箭头的视图”,即程序的Storyboard Entry Point。

    设置方法很简单:打开StoryBoard文件,选中要设置为第一视图的ViewController,在右边工具栏勾选Is Initial View Controller就好了,此时你会看到ViewCon ...

  9. eclipse中默认的提示键

    Alt+/:代码提示 Ctrl+/:注释/取消注释 Ctrl+D:删除光标所在行 Ctrl+K:将光标停留在变量上,按Ctrl+K键可以查找到下一个同样的变量 Shift+Ctrl+K:和Ctrl+K ...

  10. maven使用笔记一 下载json-lib引发的问题

    一.问题描述(IDEA中): 1,在pom.xml中配置了 <dependency> <groupId>net.sf.json-lib</groupId> < ...