【问题标题】:Redux: Accessing current state - best practice?Redux:访问当前状态 - 最佳实践?
【发布时间】:2019-01-01 00:56:12
【问题描述】:

这是我对 Redux 不了解的地方。我有一个通过项目的应用程序。您可以转到上一项和下一项。据我了解,您不应该在您的操作中访问当前状态。

关于我的应用程序,我的 redux 状态中有一个数组,其中包含我的项目的所有 id:["3123123123","1231414151","15315415", etc.] 并且我有一个包含 currently selected item 的状态(或者更好的是,它包含 id 该项目)。现在当用户点击nextItem 时,我需要获取下一项。我的(未完成的)操作如下所示:

export function nextItem(currentId) {

  //my idea:
  //take the currentId, look where in the array it is, and get the position
  //increment that position
  //get the id of the next item in the array (at position: position+1)
  //update state

  return {
    type: SET_CURRENT_ITEM,
    payload: item
  }
}

类似的事情也适用于之前的项目动作创建者。但是,我不知道如何在不访问我当前状态的情况下实现这个动作创建者?理想情况下会在哪里以及如何发生?

【问题讨论】:

  • 实际上动作创建者不应该做任何事情。它应该由参考当前状态的减速器完成。操作应该类似于“SET_NEXT_ITEM”
  • 你可以在redux中存储当前项目的索引
  • @JoaozitoPolo 我可以这样做,但这是否意味着在我的状态中引入冗余,因为我可以通过检查数组中的哪个位置找到所需的 id 来推导/计算索引?
  • @R.Kohlisch 我同意...我也不喜欢“索引”的想法...您可以使用 .findIndex() 在渲染或函数中查找索引

标签: javascript reactjs react-native react-redux flux


【解决方案1】:

我建议您发送如下操作:

{
    type: INCREMENT_CURRENT_ITEM
}

您可以直接从任何连接的组件中调度它:

dispatch({ type: INCREMENT_CURRENT_ITEM })

或者,如果您更喜欢使用动作创建器,也可以:

dispatch(incrementItem()) // incrementItem() returns the action above

在您的 reducer 中,您可以访问当前状态,您可以在其中增加项目索引,而无需在数组中搜索当前值。

【讨论】:

  • 谢谢。 In your reducer, you have access to the current state, which is where you can increment the item index - 但我只能访问我所在州的部分地区。就我而言,我需要访问不同减速器的状态,以便获得下一个 id。我该怎么做?
  • @R.Kohlisch 在没有看到minimal reproducible example 的情况下很难给出任何具体建议,但听起来你可能想要重组你的减速器并决定是否存储项目 ID 或索引,不是两者。
【解决方案2】:

我可能会添加一个组件,负责通过应用程序增加项目 ID

import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { nextItem } from "../redux/actions";

const ItemNav = ({ nextItem, items, item }) => {

  function setNextItem() {
    let currentItemID = items.indexOf(item) + 1;
    if (currentItemID >= items.length - 1) currentItemID = 0;
    nextItem(items[currentItemID]);
  }

  return (
    <ul>
      <li>previous item</li>
      <li onClick={setNextItem}>next item</li>
    </ul>
  );
};

const mapStateToProps = state => ({
  items: state.items,
  item: state.item
});

const mapDispatchToProps = dispatch => bindActionCreators({ nextItem },dispatch);

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

【讨论】:

    【解决方案3】:

    The reducer is a pure function。生产者必须收到 相同类型的参数,生产者必须计算新的 状态的版本并返回它。没有惊喜。没有副作用。不 调用第三方 API。没有变化(突变)。只有 计算新版本的状态。

    纯函数 - 在基础层面,任何不 改变输入不依赖于外部状态(数据库、DOM 或全局变量)并为相同的输入返回相同的结果 数据作为纯函数。

    另外,如果值在不同的reducer中,怎么办?

    动作创建者 - 也是纯函数,为了计算我们必须 从商店接收数据

    组件 - 在组件中使用业务逻辑不好的做法

    保留中间件,不要生产很多中间件,最好是 使用 redux-thunk

    另外,一个类似问题的链接: Redux: Reducer needs state of other Reducer?

    以及实现这种情况的第一个发现项目的链接: https://github.com/rwieruch/favesound-redux/blob/master/src/actions/player/index.js

    【讨论】:

      猜你喜欢
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2020-01-26
      • 1970-01-01
      • 2014-02-20
      相关资源
      最近更新 更多