React native 订阅Redux中存储的单个属性更改

React native 订阅Redux中存储的单个属性更改,react-native,redux,redux-framework,React Native,Redux,Redux Framework,在Redux中,我可以使用 store.subscribe(() => my handler goes here) 但是,如果我的应用商店充满了不同的对象,并且在应用程序的某个特定位置,我只想订阅应用商店中特定对象的更改,该怎么办?直接使用订阅时,无法订阅部分应用商店,但是正如Redux的创建者自己所说的那样——为了让Redux应用程序的数据流真正起作用,你需要一个组件来包装你的整个应用程序。此组件将订阅您的应用商店。其余的组件将是这个包装器组件的子组件,并且只获得它们需要的部分状态 如

在Redux中,我可以使用

store.subscribe(() => my handler goes here)

但是,如果我的应用商店充满了不同的对象,并且在应用程序的某个特定位置,我只想订阅应用商店中特定对象的更改,该怎么办?

直接使用
订阅
时,无法订阅部分应用商店,但是正如Redux的创建者自己所说的那样——为了让Redux应用程序的数据流真正起作用,你需要一个组件来包装你的整个应用程序。此组件将订阅您的应用商店。其余的组件将是这个包装器组件的子组件,并且只获得它们需要的部分状态

如果您正在使用React的Redux,那么有一个好消息-官方软件包会为您解决这个问题!它提供了称为
的包装器组件。然后,您将拥有至少一个“智能组件”,用于侦听
提供程序从存储传递的状态更改。您可以指定它应该侦听的状态部分,这些状态部分将作为道具传递给该组件(当然,它可以将它们传递给自己的子组件)。您可以通过在“智能”组件上使用函数并使用
mapstatetops
函数作为第一个参数来指定。重述:

使用订阅以存储更改的
提供程序
组件包装根组件

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

显然,
可以更好地理解这个流程。

Redux只提供了一种通用方法来了解商店何时更新:订阅
方法。对
subscribe
的回调不会获得任何关于可能已更改内容的信息,因为
subscribe
API故意是低级别的,只运行每个回调而不带任何参数。你所知道的是,商店已经以某种方式更新了

因此,必须有人编写特定的逻辑来比较旧状态和新状态,并查看是否有任何变化。您可以通过使用React-Redux来处理此问题,为组件指定
MapStateTrops
函数,在组件中实现
componentWillReceiveProps
,并检查商店中的特定道具是否已更改


还有两个插件库试图处理这种情况:和。两者基本上都允许您使用不同的方法指定要查看的状态的特定部分。

除了Andy Noelker所说的之外,
MapStateTrops
不仅将状态的一部分正确地传递到组件树中,还直接订阅在这些订阅的状态部分中所做的更改

确实,每次更改状态的任何部分时,都会调用绑定到存储的每个
MapStateTrop
函数,但与上一次调用相比,调用的结果会变浅-如果您订阅的顶级键没有更改(引用保持不变)。然后mapStateToProps将不会调用重新渲染。因此,如果你想让这个概念发挥作用,你必须保持MapStateTrops的简单,没有合并、类型改变或其他任何事情,它们应该只是传递状态的一部分


如果您想在订阅时减少状态中的数据,例如,您在状态中有列表数据,您想将其转换为以ID为键的对象,或者您想将多个状态合并到数据结构中,您应该将MapStateTrops与
createSelector
from
reselect
库中的,通过在选择器中进行所有这些修改。选择器是纯函数,用于减少和缓存作为输入传入的状态块,如果输入没有更改,则返回与上次调用时完全相同的引用,而不执行减少操作。

创建了一个hack,以帮助理解订阅者可以根据存储数据进行区分,并具有多存储功能

//从'redux'导入{createStore};
让createStore=require('redux')。createStore;
让combineReducers=require('redux')。combineReducers;
/**
*这是一个reducer,一个纯函数,具有(state,action)=>状态签名。
*它描述了一个操作如何将状态转换为下一个状态。
*
*状态的形状由您决定:它可以是一个基本体、一个数组、一个对象,
*甚至是不可变的.js数据结构。唯一重要的是你应该
*不更改状态对象,但在状态更改时返回新对象。
*
*在本例中,我们使用'switch'语句和字符串,但您可以使用
*遵循不同的约定(如函数映射),如果它对您的
*项目。
*/
功能计数器(状态=0,动作){
开关(动作类型){
案例“增量”:
返回状态+1
“减量”一案:
返回状态-1
违约:
返回状态
}
}
函数messanger(状态='Mr,khazi',动作){
开关(动作类型){
欢迎个案:
返回“你好,卡齐先生”;
案例“再见”:
回答“再见,卡齐先生”;
案例“增量”:
返回“递增的khazi”;
违约:
返回状态;
}
};
函数延迟(状态=null,操作){
开关(动作类型){
欢迎个案:
返回“$messanger”;
案例“再见”:
返回“$messanger”;
案例“增量”:
返回“$messanger,$counter”;
“减量”一案:
返回“$counter”;
违约:
返回状态;
}
};
let异径管={
计数:计数器,
信息:messanger,
行动:延迟
};
let store=createStore(
组合减速器(减速器、延迟)
);
//创建保存应用程序状态的Redux应用商店。
//它的API是{subscribe,dispatch,getState}。
//let store=createStore(计数器)
//您可以使用subscribe()更新UI以响应状态更改。
//通常你会使用
const mapStateToProps = (state) => {
    return {
        somethingFromStore: state.somethingFromStore
    }
}

class ChildOfApp extends Component {
    render() {
        return <div>{this.props.somethingFromStore}</div>
    }
}

//wrap App in connect and pass in mapStateToProps
export default connect(mapStateToProps)(ChildOfApp)