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

14 浏览
0 Comments

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

在Redux中,我可以通过store.subscribe(() => my handler goes here)轻松订阅存储更改。\n但是,如果我的存储中有许多不同的对象,并且在应用程序的特定位置,我只想订阅对存储中特定对象所做的更改呢?

0
0 Comments

在Redux中,订阅(store.subscribe)是一种常见的方式,用于在存储状态更改时更新UI或执行其他操作。然而,有时我们希望只订阅特定属性的更改,而不是整个存储状态的更改。这可能是因为我们只关心特定属性的更改,或者我们希望将订阅行为细分为更小的部分。

在上面的代码示例中,有三个reducer函数:counter、messanger和latestAction。每个reducer都处理不同的属性,并在接收到相应的action时更新该属性。然后,我们使用combineReducers将这些reducer组合成一个reducer,并将其传递给createStore函数来创建store。

在创建store后,我们使用store.subscribe函数两次来订阅store的更改。第一个订阅函数检查store的action属性,如果其中包含'messanger',则打印出相应的消息。第二个订阅函数检查store的action属性,如果其中包含'counter',则打印出相应的消息。

这种做法的出现是因为我们希望根据store数据区分订阅者,并且具有多个存储的能力。通过订阅特定属性的更改,我们可以更精确地控制订阅行为,并只在特定属性更改时执行相应的操作。

解决方法是使用store.subscribe函数来订阅特定属性的更改。在订阅函数中,我们可以通过检查store的属性来确定是否应该执行相应的操作。这可以通过使用store.getState函数来获取当前的store状态,并检查相应的属性来实现。

在上面的代码示例中,我们使用store.getState().action来获取当前的action属性,并检查其中是否包含特定关键字。如果包含特定关键字,我们执行相应的操作。

这样,我们就可以根据store数据的特定属性来订阅更改,并执行相应的操作。这种做法可以帮助我们更精确地控制订阅行为,并根据需要执行不同的操作。

总结起来,通过订阅特定属性的更改,我们可以根据store数据的不同部分来区分订阅者,并执行相应的操作。这种做法可以帮助我们更精确地控制订阅行为,并根据需要执行不同的操作。

0
0 Comments

Redux只提供了一种通用的方式来知道store何时更新:subscribe方法。subscribe的回调函数没有任何关于有什么变化的信息,因为subscribe的API是有意设定为低级别的,只是简单地运行每个回调函数而没有参数。你只知道store以某种方式进行了更新。

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

还有一些附加的库试图处理这种情况:https://github.com/ashaffer/redux-subscribe和https://github.com/jprichardson/redux-watch。两者都可以使用不同的方法指定要查看的状态的特定部分。

回答很可靠。只想补充一点,redux-watch和redux-subscribe都在Redux文档的Store推荐中列出了:https://redux.js.org/introduction/ecosystem#store。

0
0 Comments

问题的原因是在Redux中直接使用subscribe时,没有办法订阅store的一部分。但是,Redux的创建者自己说过,不要直接使用subscribe!为了使Redux应用程序的数据流正常工作,您需要一个包装整个应用程序的组件。该组件将订阅store。其余的组件将作为这个包装器组件的子组件,并且只会获取它们需要的状态的部分。

如果您正在使用React和Redux,那么有个好消息-官方的react-redux包会为您解决这个问题!它提供了一个名为的包装器组件。然后,您将至少有一个“智能组件”监听由Provider从store传递下来的状态更改。您可以指定它应该监听哪些状态的部分,并且这些状态的部分将作为props传递给该组件(然后当然,它可以将这些props传递给它自己的子组件)。您可以使用connect()函数在您的“智能”组件上使用mapStateToProps函数作为第一个参数来指定。总结一下:

使用Provider组件包装根组件以订阅store更改

ReactDOM.render(

,

document.getElementById('root')

)

现在,任何被connect()包装的的子组件都将成为“智能”组件。您可以传入mapStateToProps来选择状态的某些部分,并将其作为props传递给它。

const mapStateToProps = (state) => {

return {

somethingFromStore: state.somethingFromStore

}

}

class ChildOfApp extends Component {

render() {

return

{this.props.somethingFromStore}

}

}

//将App包装在connect中并传入mapStateToProps

export default connect(mapStateToProps)(ChildOfApp)

显然,可以有很多子组件,您可以自由选择为的每个子组件监听哪些状态的部分。我建议阅读有关使用React的文档,以更好地理解这个流程。

一个问题是,我想有一个组件来响应一个action。假设有一个组件NavBar,它触发一个action toggleDrawer。这个action将一个值存储在store中,表示drawer的状态isDrawerOpen。那么,当触发该action时,我如何使drawer打开?这里还存在一个潜在的冲突:drawer本身可以打开,并且它控制它的open属性,因此从drawer更改isDrawerOpen会导致无限循环...

在connect中仍然有代码来响应所有更改,并在比较前后的mapStateToProps返回之前至少执行一些代码,从而不必要地影响性能。我只是想知道是否可以检测所需的键的名称,例如:function mapStateToProps(({someKey, anotherReducerKey}) => ...,并且只订阅这些键。在JavaScript中,您可以获取参数的名称-因此问题是您是否可以获取这些参数的解构键的名称。

更新:以下是如何获取参数名称的方法:获取参数名称的方法:stackoverflow.com/questions/1007981/… ...然后我只是使用func.toString()来查看是否可以获取解构对象参数,确实可以!因此,我们可以重写该函数来获取您想要订阅的状态键。然后我们只需要实现一个store.subscribeByKey()函数。

然而,还有两个问题:1)我们如何以跨浏览器兼容的方式实现这一点,因为并非所有浏览器都原生支持像Chrome控制台那样的解构,2)如果这的确比connect运行mapStateToProps(以及mapDispatchToProps和mergeProps)函数更快,这将在一定程度上取决于您的应用程序,而不仅仅是connect函数。也就是说,我认为我们只需要在启动时运行它一次以获取您要监视的键,因为我认为可以静态分析connect函数调用,即在运行时不能更改。

在这个特定的例子中,export default connect...的目的是什么?为什么要导出它?

我的意思是,如果您的应用程序是扁平的,而不是拆分成需要输入和导出的文件,那么如何将store连接到每个组件,以便它们可以访问它?

0