在mapStateToProps之前初始化状态?

时间:2019-07-10 08:15:45

标签: javascript reactjs redux react-redux antd

我知道我的问题来自对react-redux的误解,但我将描述我的用例,希望有人能指出正确的方向。

我正在尝试在redux存储内部存储表(蚂蚁设计表)中的选定行键(selectedRowKeys)。像这样简单的商店结构,一切都可以正常工作:

selectedRowKeys: []

但是我想以规范化的形式存储该状态以处理多个表和多个表属性:

tables: {
 123fdfas-234dasf-234asdf-23rfa : { //table id
    id: 123fdfas-234dasf-234asdf-23rfa,
    selectedRowKesy: []
    //... other properities
    }
}

问题是当redux试图像这样映射mapStateToProps时,此状态不存在:

const mapStateToProps = (state, ownProps) => {
  if (!ownProps.id) {
    ownProps.id = uuidv4();
  }

  return {
    selectedRowKeys: state.tables[ownProps.id].selectRowKeys
  };
};

state.tables[ownProps.id]未定义,所以出现错误。

我认为我需要以某种方式初始化状态,但这使我更加困惑。到目前为止,我已经弄清楚了:

  • 我无法像reducerName (state = initialState, action)这样的化简器中初始化状态,因为没有调度动作,也没有action.id(动作对象的有效载荷具有表ID)。
  • 我无法在INIT_TABLE中调度动作componentDidMount(),因为mapStateToProps首先执行,所以state.tables[ownProps.id]仍未定义。

我觉得这个用例很奇怪,尽管我已经搜寻并思考了3天,但我还是找不到解决方案。

请指导我,我陷入了疯狂循环:)

这是我的第一个SO问题,请让我知道是否不清楚。

2 个答案:

答案 0 :(得分:1)

谁负责创建新表?这是解决此问题的决定因素。

绝对不应该在Log4J中创建ID,并且您不应该突变mapStateToProps。我什至感到惊讶,甚至还行。如果使用redux,则应在操作中创建ID。

如果您的React-app具有某种机制来创建新表(例如,用户单击按钮),那么您应该在其中调度初始化动作。如果您确实找不到负责表初始化的父组件,则可能是该组件的责任,您应该在ownProps中分派操作。

无论您选择哪个选项,您的componentDidMount都应优雅地处理空状态,即。如果mapStateToProps丢失,则应将其设置为某个默认值(可能是空数组还是null?)。如果没有可用的默认值,则组件应处理缺失值。通常在渲染功能中进行一些空检查,这些空检查会返回selectedRowKeys直到数据可用。

答案 1 :(得分:0)

从我的理解到问题,您太具体了!

在这种情况下,这不是一个好习惯。 我建议如下。

假设您拥有减速器tables

const mapStateToProps = ({ tables }, ownProps) => {
  return {
    tables,
  };
};

这将使减速器tables在组件的this.props

中可用

因此,您可以在组件中的任何位置进行以下操作以获取选定的行,定义此方法并在适当的位置使用它,而不是直接在mapStateToProps中这样做,这不是一个好习惯。

getSelectedRowKeys = (ownProps) => {
  if (!ownProps.id) {
    ownProps.id = uuidv4();
  }
  const selectedRowKeys = [];
  const table = this.props.tables[ownProps.id];
  const selectedRowKeys = table && table.selectRowKeys; //if table exists get the row keys.

  return selectedRowKeys || []; //if selectedRowKeys are not there return an empty array.
}