[Redux] Passing the Store Down with <Provider> from React Redux
Previously, we wrote the Provider component by ourself:
class Provider extends Component {
getChildContext() {
return {
store: this.props.store
};
}
render() {
return this.props.children;
}
}
Provider.childContextTypes = {
store: React.PropTypes.object
};
Then we can get 'store' from the 'context' from each child container component:
class VisibleTodoList 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 (
<TodoList
todos={
getVisibleTodos(
state.todos,
state.visibilityFilter
)
}
onTodoClick={id =>
store.dispatch({
type: 'TOGGLE_TODO',
id
})
}
/>
);
}
}
VisibleTodoList.contextTypes = {
store: React.PropTypes.object
};
or Persentiaonal component:
const AddTodo = (props, { store }) => {
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>
);
};
AddTodo.contextTypes = {
store: React.PropTypes.object
};
Because the solution is so convenient, we can use library instead of writing our own Provider:
So we can remvoe all the whole Provider class component, instead of we do:
const {Provider} = ReactRedux;
In html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.0/react-redux.js"></script>
---------
Code:
<!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>
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,
children,
onClick
}) => {
if (active) {
return <span>{children}</span>;
}
return (
<a href='#'
onClick={e => {
e.preventDefault();
onClick();
}}
>
{children}
</a>
);
};
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
};
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;
const AddTodo = (props, { store }) => {
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>
);
};
AddTodo.contextTypes = {
store: React.PropTypes.object
};
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() {
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 (
<TodoList
todos={
getVisibleTodos(
state.todos,
state.visibilityFilter
)
}
onTodoClick={id =>
store.dispatch({
type: 'TOGGLE_TODO',
id
})
}
/>
);
}
}
VisibleTodoList.contextTypes = {
store: React.PropTypes.object
};
const TodoApp = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
);
const {Provider} = ReactRedux;
const { createStore } = Redux;
ReactDOM.render(
<Provider store={createStore(todoApp)}>
<TodoApp />
</Provider>,
document.getElementById('root')
);
[Redux] Passing the Store Down with <Provider> from React Redux的更多相关文章
- [Redux] Passing the Store Down Implicitly via Context
We have to write a lot of boiler plate code to pass this chore down as a prop. But there is another ...
- [Redux] Passing the Store Down Explicitly via Props
n the previous lessons, we used this tool to up level variable to refer to the Redux chore. The comp ...
- react + redux 实现幻灯片
写在前面: 这一篇是我 使用scss + react + webpack + es6实现幻灯片 的进阶篇,效果请点我,将会使用上redux的基础用法,因为一开始没有理解好redux的用法,单纯看文档, ...
- 【原】react+redux实战
摘要:因为最近搞懂了redux的异步操作,所以觉得可以用react+redux来做一个小小的项目了,以此来加深一下印象.切记,是小小的项目,所以项目肯定是比较简单的啦,哈哈. 项目效果图如图所示:(因 ...
- React & Redux 的一些基本知识点
一.React.createClass 跟 React.Component 的区别在于后者使用了ES6的语法,用constructor构造器来构造默认的属性和状态. 1. React.createCl ...
- [Redux] Generating Containers with connect() from React Redux (AddTodo)
Code to be refacted: const AddTodo = (props, { store }) => { let input; return ( <div> < ...
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
- react+redux教程(四)undo、devtools、router
上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...
随机推荐
- Spring简单的小例子SpringDemo,用于初略理解什么是Spring以及JavaBean的一些概念
一.开发前的准备 两个开发包spring-framework-3.1.1.RELEASE-with-docs.zip和commons-logging-1.2-bin.zip,将它们解压,然后把Spri ...
- WPF之Binding的使用
引出: 在WPF中Binding可以比作数据的桥梁,桥梁的两端分别是Binding的源(Source)和目标(Target).一般情况下,Binding源是逻辑层对象,Binding目标是UI层的控件 ...
- 免费SVN源代码在线托管
免费的SVN源代码在线托管网站很多,用的最多的是TaoCode吧.但是一般都要求开源,支持私有项目的普遍收费,要不就是流量很少,不够用.对比了一下,发现好库正好能满足需要. 网址: http://ww ...
- MVC项目发布IIS访问不了
首先在配置文件上加红色字体这个配置 用来打印错误信息,再根据错误信息来处理 <system.webServer> <validation validateIntegratedMode ...
- x++ and ++x
http://blog.sina.com.cn/s/blog_6c762bb30101ar1w.html 看到个东西,搞不清的时候可以看看 =.=
- oracle 优化 —— 分区表
一.分区表简介 分区表类型:[范围分区].[列表分区] [hash分区] [这些分区的组合分区] 范围分区:以某一个范围进行分区.eg:时间段划分. 列表分区:以某一些几个值进行分区.eg:地区 ...
- cocos2dx Sprite的多种创建方法
1.通过文件创建 Sprite *bg = Sprite::create("backGround.jpg"); 2.通过图片的某个区域创建 SpriteFrame *frame = ...
- 武汉科技大学ACM :1010: 华科版C语言程序设计教程(第二版)例题7.8
Problem Description 输入一个用年月日表示的日期,求该日期是该年的第几天.输入某年的第几天,输出这一天是该年的几月几号,茂茂解不出,需要你的帮助. Input 开始有个整数k,表示询 ...
- HTML5 布局标签
HTML5是HTML标准的下一个版本.越来越多的程序员开始HTML5来构建网站,相对HTML4,HTML5新增的带有语义化的标签可以代替div进行页面布局(与html5.js结合起来时可以放心使用 ) ...
- python类方法与对象方法学习
class Test_Demo: TEST = 'test_value' def __init__(self,name,age): self.name = name self.age = age #s ...