//import { createStore } from 'redux';
let createStore = require('redux').createStore;
let combineReducers = require('redux').combineReducers;
/**
* This is a reducer, a pure function with (state, action) => state signature.
* It describes how an action transforms the state into the next state.
*
* The shape of the state is up to you: it can be a primitive, an array, an object,
* or even an Immutable.js data structure. The only important part is that you should
* not mutate the state object, but return a new object if the state changes.
*
* In this example, we use a `switch` statement and strings, but you can use a helper that
* follows a different convention (such as function maps) if it makes sense for your
* project.
*/
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
function messanger(state = 'Mr, khazi', action) {
switch(action.type) {
case 'WELCOME':
return 'Hello, Mr Khazi';
case 'BYE':
return 'Bye, Mr Khazi';
case 'INCREMENT':
return 'Incremented khazi';
default:
return state;
}
};
function latestAction(state = null, action) {
switch(action.type) {
case 'WELCOME':
return '$messanger';
case 'BYE':
return '$messanger';
case 'INCREMENT':
return '$messanger, $counter';
case 'DECREMENT':
return '$counter';
default:
return state;
}
};
let reducers = {
counts: counter,
message: messanger,
action: latestAction
};
let store = createStore(
combineReducers(reducers, latestAction)
);
// Create a Redux store holding the state of your app.
// Its API is { subscribe, dispatch, getState }.
//let store = createStore(counter)
// You can use subscribe() to update the UI in response to state changes.
// Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly.
// However it can also be handy to persist the current state in the localStorage.
store.subscribe(() => {
if(store.getState().action.indexOf('messanger') !== -1) {
console.log('subscribed for counter actions', store.getState());
}
});
store.subscribe(() => {
if (store.getState().action.indexOf('counter') !== -1) {
console.log('subscribed for messanger actions', store.getState());
}
});
// The only way to mutate the internal state is to dispatch an action.
// The actions can be serialized, logged or stored and later replayed.
console.log('----------------Action with both subscriber-------------');
store.dispatch({ type: 'INCREMENT' });
console.log('---------------Action with counter subscriber-----------');
store.dispatch({ type: 'DECREMENT' });
console.log('---------------Action with messenger subscriber---------');
store.dispatch({ type: 'WELCOME' });
/*
every reducer will execute on each action.
* /
4条答案
按热度按时间dgsult0t1#
当直接使用
subscribe
时,无法订阅商店的一部分,但正如Redux的创建者自己所说--不要直接使用subscribe
!要使Redux应用的数据流真正工作,您将需要一个组件来 Package 整个应用程序。此组件将订阅您的商店。其余组件将是此 Package 器组件的子组件,并且将仅获得它们所需的状态部分。如果您正在使用Redux with React,那么有一个好消息-官方的react-redux包会为您解决这个问题!它提供了一个 Package 器组件,称为
<Provider />
。这样,您将拥有至少一个“智能组件,”该组件侦听由Provider
从存储传递下来的状态更改。您可以指定它应该侦听状态的哪些部分,并且这些状态片段将作为道具传递给该组件(当然,它也可以将这些状态片段传递给它自己的子组件)。您可以通过在“智能”组件上使用connect()函数并使用mapStateToProps
函数作为第一个参数来指定这一点。使用订阅存储更改的
Provider
组件 Package 根组件现在,
<App />
的任何一个用connect()
Package 的子元素都将是一个“智能”组件,您可以传入mapStateToProps
来选择状态的某些部分,并将这些部分作为道具。显然,
<App />
可以有很多子级,您可以选择mapStateToProps
应该为每个子级监听状态的哪些部分。我建议阅读有关usage with React的文档,以便更好地理解此流程。vq8itlhq2#
Redux只提供了一种通用的方法来了解商店何时更新:
subscribe
方法。对subscribe
的回调不会获得任何有关可能已更改的信息,因为subscribe
API故意设置为低级别,并且只是在不使用参数的情况下运行每个回调。您所知道的只是存储区以某种方式进行了更新。因此,必须编写特定的逻辑来比较旧状态和新状态,并查看是否有任何变化。您可以使用React-Redux来处理此问题,为组件指定一个
mapStateToProps
函数,在组件中实现componentWillReceiveProps
,并检查商店中的特定属性是否发生了变化。也有一些插件库尝试处理这种情况:https://github.com/ashaffer/redux-subscribe和https://github.com/jprichardson/redux-watch。基本上,这两种方法都允许您使用不同的方法指定要查看的状态的特定部分。
eblbsuwk3#
除了Andy Noelker所说的,
mapStateToProps
不仅将状态的一部分正确地传递到组件树,它还订阅直接在状态的这些订阅部分中所做的更改。确实,每次状态的任何部分发生更改时,都会调用绑定到存储的每个
mapStateToProp
函数,但是与上一次调用相比,调用的结果会变浅--如果您订阅的顶级键没有更改的话(引用保持不变)。那么mapStateToProps就不会调用re-render。所以如果你想让这个概念起作用,你必须保持mapStateToProps的简单,没有合并,类型改变或任何东西,他们应该简单地传递状态的一部分。如果您希望在订阅时减少状态中的数据,例如,您在状态中有列表数据,并且您希望将其转换为以id作为键的对象,或者您希望将多个状态加入到数据结构中,则应该将mapStateToProps与
reselect
库中的createSelector
组合在一起。选择器是纯函数,它们减少并缓存作为输入传入状态块,如果输入没有改变-它们返回与上次调用时完全相同的引用,而不执行归约。ep6jt1vc4#
创建了一个黑客来帮助了解用户可以根据商店数据进行区分,具有多个商店的能力。