Javascript 在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事件做

假设您有两个对象要存储在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
事件做出反应,并创建一个新的
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
        ];
    }
}