Javascript 在Redux中同时添加多个连接对象
假设您有两个对象要存储在Redux中,Javascript 在Redux中同时添加多个连接对象,javascript,redux,Javascript,Redux,假设您有两个对象要存储在Redux中,A和B,这两个对象按照进行了非规范化,如下所示: state = { a: { byId: { id: { obj } }, allIds: [] }, b: { byId: { id: { obj } }, allIds: [] } }; 您有一个操作,CREATE_A,它向存储添加一个新的A但是,对于创建的每个A,它本身也需要一个B。假设A和B在单独的减速器片中(即组合减速器),不能合并为一个 很容易让B的reducer对CREATE_A事件做
A
和B
,这两个对象按照进行了非规范化,如下所示:
state = {
a: { byId: { id: { obj } }, allIds: [] },
b: { byId: { id: { obj } }, allIds: [] }
};
您有一个操作,CREATE_A
,它向存储添加一个新的A
但是,对于创建的每个A
,它本身也需要一个B
。假设A
和B
在单独的减速器片中(即组合减速器
),不能合并为一个
很容易让B
的reducer对CREATE_A
事件做出反应,并创建一个新的B
,但是如果B
对象需要刚刚创建的A
的ID怎么办
即使有一个被邀请加入B
到a
,仍然存在“知道首先创建的a
的问题”。我提出的解决方案是存储上次创建的A
,如下所示:
a: { lastCreated: {}, byId: etc, allIds: etc }
然后将整个状态树传递给B
的reducer或联接表reducer,这样它就可以访问state.a.lastCreated
。但是,仅仅拥有一把钥匙让后来的减速机知道发生了什么感觉是不对的(减速机需要特定顺序的想法似乎也是错误的)
我认为您也可以使用新的a
的id分派CREATE_B
,但这必须在异步操作中完成(因为您不能从reducer分派),这也感觉不太正确
在程序世界中,这将是微不足道的:
a = createA();
createB(a);
但即使有两份报告,我也不确定它将如何工作:
dispatch( createA() )
dispatch( createB(???) )
处理这种“A-固有意味着B-也”的情况的最佳方式是什么
编辑:让我试着用一些更具体的例子
假设你有square
s和point
s。创建一个正方形
本质上意味着创建4个点
s。这些点与正方形相连,因为它们构成正方形,但它们也不属于正方形,因为它们可以是独立的对象:
因此,ADD_SQUARE
既需要添加一个正方形,又需要添加4个点,然后将这两个点连接在一起,我不知道如果不直接在父“状态”中这样写一个减速机,如何才能做到这一点(我不想这样做,它会很快变得非常混乱,想象一下必须重复3-8边多边形):
您可以在A和B减缩器中定义相同的操作。。像这样-- 然后,当您分派操作时,它将影响两个减速器
function createA({id, stuff, etc}) {
return {
type: "A_CREATE",
payload: {id, stuff, etc}
}
}
然后你可以将id绑定到你需要创建的任何东西上。。。从而将它们“连接”在一起
编辑:
您可以使用redux thunk或其他一些中间件,如redux saga,并承诺分派多个操作
`
function handleACreation(payload) {
dispatch(
createA(payload)
.then(result => dispatch(updateB(result)))
)
}
`
很明显,精确的代码是行不通的,但总体思路仍然是:]希望这能有所帮助 在我的例子中,我通过在action creator中而不是在
A
的reducer中创建A
的id来解决这个问题。比如说,
function createSquare () {
return {
type: CREATE_SQUARE,
id: newUuid()
};
}
function squareReducer ( state, action ) {
switch ( action.type ) {
case CREATE_SQUARE:
return { id: action.id };
}
}
function pointReducer ( state, action ) {
switch ( action.type ) {
case CREATE_SQUARE:
return [
{ id: newUuid(), square: action.id }
{ id: newUuid(), square: action.id } //etc
];
}
}
不过,我仍然愿意接受其他解决方案。谢谢,但我已经在这样做了,请参见第3段
B
的减速机仍然需要知道创建了什么A
。您不能通过操作的有效负载将此信息发送到B的减速机吗?在动作的有效载荷中,您可以将创建的A的id发送到B,并将此id与您创建的任何东西绑定……A的id只有在创建了A
之后才知道。问题不在于A_更新
,而在于A_创建
。您是否考虑过使用redux thunk来处理此类副作用?您可以改为在A_CREATE中分派一个将创建A的操作,然后(当此创建完成时)将另一个操作分派到B的减速机,例如:分派(doThis())。然后(()=>dispatch(doThis())在我的问题中也谈到了这一点。认为有些东西可以是同步的而不是异步的是不对的。例如,如果与React一起使用,第一个分派将导致重新呈现中间的“半完成”状态,这可能会导致错误。
`
function handleACreation(payload) {
dispatch(
createA(payload)
.then(result => dispatch(updateB(result)))
)
}
`
function createSquare () {
return {
type: CREATE_SQUARE,
id: newUuid()
};
}
function squareReducer ( state, action ) {
switch ( action.type ) {
case CREATE_SQUARE:
return { id: action.id };
}
}
function pointReducer ( state, action ) {
switch ( action.type ) {
case CREATE_SQUARE:
return [
{ id: newUuid(), square: action.id }
{ id: newUuid(), square: action.id } //etc
];
}
}