我知道我的问题来自对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问题,请让我知道是否不清楚。
答案 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.
}