编写react-redux
应用程序时,我需要在全局状态树中保留应用程序和UI状态。设计它的最佳方法是什么?
假设我有一个待办事项列表:
{
items: [
{ id: 1, text: 'Chew bubblegum' },
{ id: 2, text: 'Kick ass' }
]
}
现在我想让用户选择并展开项目。如何建模状态形状(至少)有两种选择:
{
items: [
{ id: 1, text: 'Chew bubblegum', selected: true, expanded: false },
{ id: 2, text: 'Kick ass', selected: false, expanded: false }
]
}
但这是将UI状态(selected
和expanded
)与应用程序状态混合在一起。当我将待办事项列表保存到服务器时,我想只保存应用程序状态,而不是UI状态(在真实应用程序中,UI状态可以包含模态对话框的状态,错误消息,验证状态等)。
另一种方法是为项目的UI状态保留另一个数组:
{
items: [
{ id: 1, text: 'Chew bubblegum' },
{ id: 2, text: 'Kick ass' }
],
itemsState: [
{ selected: true, expanded: false },
{ selected: false, expanded: false }
]
}
然后在渲染项目时必须将这两种状态组合在一起。我可以想象你可以在zip
函数中connect
这两个数组来简化渲染:
const TodoItem = ([item, itemState]) => ...;
const TodoList = items => items.map(item => (<TodoItem item={item} />));
export default connect(state => _.zip(state.items, state.itemsState))(TodoList);
但状态更新可能很痛苦,因为items
和itemsState
必须保持同步:
还有其他选择吗?或者是否有任何库可以帮助保持应用状态和UI状态同步?
答案 0 :(得分:12)
受normalizr启发的另一种方法:
{
ids: [12,11], // registry and ordering
data: {
11: {text: 'Chew bubblegum'},
12: {text: 'Kick ass'}
},
ui: {
11: { selected: true, expanded: false },
12: { selected: false, expanded: false }
}
}
答案 1 :(得分:0)
我目前正在考虑这个侧面项目。我将接近它类似于上面的Rick方法。数据{}作为事实的来源,您可以使用它来推动本地ui变化(反映最新状态)。你需要在渲染之前将数据和ui合并在一起,我自己也在几个地方尝试过。我会说,就保持同步而言,它不应该太糟糕。基本上,无论何时保存/获取数据,您都要更新数据{}并清除ui {}以准备下一个用例。