如何在 Redux 中为每个实例创建一个存储?

2024-02-24

有时,在 Redux 应用程序中为每个实例创建一个存储会很有用。 Redux 的创建者自己创建了一个 Gist 来描述如何实现这一点:https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400 https://gist.github.com/gaearon/eeee2f619620ab7b55673a4ee2bf8400

我已经在 Gist 中问过这个问题,但我认为 StackOverflow 是解决这个问题的更好地方:

我想知道如何dispatch对组件自己的特殊存储的操作?有没有办法访问store- 的支柱<Provider />对于每个<SubApp />(及其子组件)?

例如:我有一些 API 类调用dispatch从远程服务器获取数据后。但由于我无法导入“普通”存储,那么处理自定义存储以使它们可用于其他类/文件/服务的最佳方法是什么?

Update 1

所以我让它工作了,但我认为这是一种非常肮脏的方式(注意UGLY?代码中的注释):

提供商:

通过在构造函数内创建存储来为每个实例创建一个存储:

export default class OffersGridProvider extends React.Component {
  constructor(props) {
    super(props)
    this.store = createStore(reducers);
  }

  render() {
    return (
      <Provider store={this.store}>
        <OffersGridContainer offers={this.props.offers} />
      </Provider>
    );
  }
}

容器:

提供者注入一个dispatch方法用于this存储到我的OffersGridContainer我可以用它来将操作分派到该实例的存储:

class OffersGridContainer extends React.Component {    
  componentDidMount() {

    // UGLY???
    const { dispatch } = this.props;

    let destinationIds = [];
    this.props.offers.forEach((offer) => {
      offer.to.forEach((destination) => {
        destinationIds.push(destination.destination);
      });
    });

    // MORE UGLY???
    destinationsApi.getDestinations(dispatch, destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

export default connect(mapStateToProps)(OffersGridContainer);

API方法:

只需使用dispatch-我作为参数传递给 API 方法的方法:

export function getDestinations(dispatch, ids) {
  const url = $('meta[name="site-url"]').attr('content');

  const filter = ids.map((id) => {
    return `filter[post__in][]=${id}`;
  }).join('&');

  return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`)
    .then(response => {
      dispatch(getOffersGridSuccess(response.data));
      return response;
    });
}

Update 2

刚刚收到有关的提示mapDispatchToProps在评论中,所以我的Container现在看起来像这样:

class OffersGridContainer extends React.Component {    
  componentDidMount() {
    let destinationIds = [];

    this.props.offers.forEach((offer) => {
      offer.to.forEach((destination) => {
        destinationIds.push(destination.destination);
      });
    });

    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    getDestinations: function(ids) {
      return destinationsApi.getDestinations(dispatch, ids);
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);

更新3(最终答案)

现在一切正常了!下面是代码:

提供商:

export default class OffersGridProvider extends React.Component {    
  constructor(props) {
    super(props)
    this.store = createStore(reducers, applyMiddleware(thunk));
  }

  render() {
    return (
      <Provider store={this.store}>
        <OffersGridContainer offers={this.props.offers} />
      </Provider>
    );
  }
}

容器:

class OffersGridContainer extends React.Component {
  componentDidMount() {
    const destinationIds = this.props.offers.reduce((acc, offer) => {
      return [...acc, ...offer.to.map(d => d.destination)];
    }, []);

    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    getDestinations: function(ids) {
      return dispatch(destinationsApi.getDestinations(ids));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);

API方法:

export function getDestinations(ids) {
  return function(dispatch) {
    const url = $('meta[name="site-url"]').attr('content');

    const filter = ids.map((id) => {
      return `filter[post__in][]=${id}`;
    }).join('&');

    return axios.get(`${url}/wp-json/wp/v2/destinations?filter[posts_per_page]=-1&${filter}`)
      .then(response => {
        return dispatch(getOffersGridSuccess(response.data));
      });
  }
}

我建议您不要直接在组件中进行 api 调用,而是使用redux-thunk包裹。

接下来,你应该通过mapDispatchToProps函数作为第二个参数connect函数,将动作创建器函数注入到组件中:

import { getDestinations } from '../actions';

class OffersGridContainer extends React.Component {    
  componentDidMount() {
    // Tip.
    const destinationIds = this.props.offers.reduce((acc, offer) => {
      return [...acc, ...offer.to.map(d => d.destination)];
    }, []);

    // instead `destinationsApi.getDestinations(dispatch, destinationIds)`
    // call action creator function
    this.props.getDestinations(destinationIds);
  }

  render() {
    return (
      <OffersGridLayout destinations={this.props.destinations} />
    );
  }
}

const mapStateToProps = function(store) {
  return {
    destinations: store.offersGridState.destinations
  };
}

const mapDispatchToProps = function(dispatch) {
  return {
    // this function will be available in component as   
    // `this.props.getDestinations`.
    getDestinations: function(destinationIds) {
      dispatch(getDestinations(destinationIds));
    }
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(OffersGridContainer);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Redux 中为每个实例创建一个存储? 的相关文章

随机推荐

  • 替换公式中的文本时发现错误

    我发现了一个非常有趣的bug今天 即如果它是bug 您能确认一下是否可以复制吗 如果它是一个错误并且尚未报告 那么我可以将其归档 如果任何 Excel MVP 想要将其作为错误归档 我也可以接受 让我们说在sheet1在细胞内A1 你有一个
  • 求给定 Int 的总和但忽略重复的数字

    我不能使用数组或列表 我必须使用 C 重复意味着如果你有975444579它会显示25或者如果你有32111它会显示6并不是8 这是我的代码 include
  • Spring OAuth2 JDBCTokenStore 性能和数据库架构

    我使用 MySQL5 5 REST Jersey Spring Security Spring OAuth2 现在我正在做性能测试并注意到 org springframework security oauth2 provider token
  • F# 受歧视联合的限制

    我正在尝试将一个小型编译器从 C 移植到 F 以利用模式匹配和可区分联合等功能 目前 我正在使用基于 System Linq Expressions 的模式对 AST 进行建模 一个抽象基 Expression 类 每个表达式类型的派生类
  • 显示两个日期之间的所有日期数据;如果特定日期不存在行,则所有列中显示零

    我想显示两个日期之间的所有日期 当缺少任何日期数据时 它应该在 val 列中显示零 declare temp table id int identity 1 1 not null CDate smalldatetime val int 插入
  • 使用javascript设置图像源和背景图像

    我看过许多其他帖子 我认为我正在使用建议的确切语法 但是 我没有让图像显示出来 我有一个jsfiddle http jsfiddle net abalter An7r5 是jsfiddle的问题吗 它也无法在我正在开发的网站上运行 div
  • 固件:配置 orion 上下文代理端口

    我在用着Orion 上下文代理 http catalogue fi ware org enablers publishsubscribe context broker orion context broker但默认端口在我的组织中无效 防火
  • 为 UIImagePickerController 启用 HDR 选项

    是否可以在我的应用程序中启用 HDR 选项 我以为它会自动存在 我寻找了其他媒体类型 认为 kUTTypeHDRImage 可能是一个选择 但没有这样的运气 它不是额外的源类型 也不能通过cameraCaptureMode使用 ipc so
  • 如何在codeigniter中调用另一个控制器中的一个控制器函数

    我有一个名为home php其中一个函数名为podetails有没有 我想在另一个控制器中调用这个函数user php 可以这样做吗 我读过关于HMVC在CI中 但我想知道是否可以不使用hmvc 要扩展控制器 请按照此操作tutorial
  • 使用异常映射器进行 Openejb Rest 集成测试

    我正在为我的 jax rs 服务编写一些集成测试 其中我有一组异常映射器 因此 在执行给定请求时 我期望基于异常映射器的特定响应代码 问题是在这个环境中运行时我无法调用异常映射器 我的服务应该在我的测试中抛出逻辑异常 Stateless P
  • 如何在 HTML 下拉列表中显示复选框?

    我需要填充一个下拉列表 HTML
  • 引用库中的 ASP.NET 相对路径

    我有一个 ASP NET 网站 我正在其中从 xml 文件加载一些验证规则 此 xml 文件名没有路径信息 被硬编码在库中 我知道硬编码名称不好 但我们就在这个例子中使用它 当我运行该网站时 ASP NET 尝试在source路径 名称硬编
  • PRESTASHOP NGINX + 重写规则

    我一直在为这种组合寻找一个好的解决方案 并遵循以下步骤 http www phamviet net 2012 06 03 prestashop rewrite url on nginx http www phamviet net 2012
  • Android模拟器没有窗框

    我是 Android 开发新手 并且对 Android 模拟器有疑问 它没有窗口框架 我无法将其移动到屏幕上或移动到第二个显示器 这让我很害怕 我尝试用谷歌搜索 但没有找到解决方案 谁能告诉我如何解决这个问题 我有同样的问题 有一个框架 它
  • Spring Boot 中的大小注释返回 400 Bad Request

    我在执行时没有收到消息错误 SizeSpring Boot bean 类中的注释 下面是我的文件 pom xml
  • 我可以在不先查询 EF 实体的情况下更新它吗?

    这是我的场景 我有一条通过 WCF 传递的简单消息 该消息代表现有数据库记录并具有all进行计算所需的数据字段 一旦我完成了计算 我想更新one该数据记录上的字段 目前 尝试简单地设置实体框架版本的所有字段 然后保留对象上下文的状态似乎没有
  • 如何获得两个具有不同绘图的窗口

    当我们有一个带有绘图的窗口时 有没有办法告诉 R 在新窗口中显示新绘图 plot 1 1 dev new plot 2 2 dev set dev prev go back to first title main test dev 1 de
  • 连接 ECONNREFUSED - 节点 js 、 sql

    我在 js 文件中有下一个代码 var mysql require mysql var TEST DATABASE nodejs mysql test var TEST TABLE test var client mysql createC
  • SWIFT 在 Main.storyboard 中定义的 UIImageview 中旋转图像

    我是 SWIFT 新手 正在练习学习 但在某些方面遇到了一些困难 我在 Main storyboard 定义的 UIImageview 中有一个图像 我需要旋转它 我有一个 IBOutlet 定义为 IBOutlet weak var im
  • 如何在 Redux 中为每个实例创建一个存储?

    有时 在 Redux 应用程序中为每个实例创建一个存储会很有用 Redux 的创建者自己创建了一个 Gist 来描述如何实现这一点 https gist github com gaearon eeee2f619620ab7b55673a4e