如何在react redux中访问“商店”?(或如何链接动作)

IT技术 reactjs redux
2021-05-14 17:41:27

我正在尝试向我的商店添加一个侦听器。我在网上找到的每个例子似乎都在使用store.subscribe(() => function here)

但是,我无法从任何非根组件访问“商店”。我发现引用了一些关于它的问题(How to access store in second component in react-redux)但他们只谈论使用Provider=storeHOC访问props/动作,而不是访问商店本身来做一些事情,比如向店铺。

(对于我的特定用例,如果“activeUser”发生变化,我想听商店的声音,如果发生变化,则触发一系列附加操作。我相信这可能可以通过 thunk 解决,并且只需将操作链接到“setActiveUser”操作......所以这个问题更多的是关于如何实际让听众进入商店而不是这个特定问题)

2个回答

您要实现的是命令式编程。react-redux 是围绕 React 的声明性特性设计的,因此可以防止您的组件直接访问 store。

一个肮脏的解决方案是从创建它的 Javascript module中导出存储,使其可以被应用程序的任何其他module访问。这样您就可以在任何地方进行订阅,而不仅仅是您的“根组件”。然而,这是一种反模式,应该避免。

解决您问题的最佳解决方案是接受 React 的声明性性质并执行以下操作:

我的组件容器.js

import {connect} from 'react-redux';
import {MyComponent} from './MyComponent';

function mapStateToProps(state) {
  return {
    activeUser: /* extract the active user from the state object */
  };
}

export const MyComponentContainer = connect(mapStateToProps)(MyComponent)

我的组件.js

import React from 'react';

export class MyComponent extends React.Component {
  componentDidMount() {
      this.yourChainOfActions(this.props.activeUser);
  }

  componentDidUpdate(prevProps) {
    if(this.props.activeUser.id !== prevProps.activeUser.id) {
      this.yourChainOfActions(this.props.activeUser);
    }
  }

  yourChainOfActions = (activeUser) => {
    // ...
  };

  render() {
    // ...
  }
}

这需要一些思维转变,但这是使用 React 强制响应变化的最佳方式(直到出现钩子

- 编辑 -

如果“yourChainOfActions”包含在一堆store.dispatch()调用中,则您需要授予MyComponent对该store.dispatch函数的访问权限通常,您不会直接传递此函数,而宁愿在MyComponentContainer's 中创建一个包装器mapDispatchToProps,如下所示:

我的组件容器.js

import {connect} from 'react-redux';
import {MyComponent} from './MyComponent';

function mapStateToProps(state) {
  return {
    activeUser: /* extract the active user from the state object */
  };
}

function mapDispatchToProps(dispatch) {
  return {
    onActiveUserChange(activeUser) {
       // use dispatch however you wish here
    }
  }
}

export const MyComponentContainer = connect(mapStateToProps, mapDispatchToProps)(MyComponent)

MyComponent现在可以onActiveUserChange通过它的 props访问该函数,你可以在它的componentDidUpdate生命周期中使用它

您可能决定将其拆分onActiveUserChange为一组单独的函数以获得更好的可组合性。这取决于您和您的用例。

快速回答是不要在您的组件中执行此操作!

通常这会在您定义/构建您的商店时完成。也许您有一个将此订阅耦合到组件的用例,但如果是这样,我会感到非常惊讶。

有了这个解决方案,商店自己照顾自己,而组件对它完全是被动的——只是触发动作并接收减少的数据。它们不应影响数据流的业务逻辑。