Javascript 状态数组上的多个不可变更改

Javascript 状态数组上的多个不可变更改,javascript,reactjs,ecmascript-6,redux,immutability,Javascript,Reactjs,Ecmascript 6,Redux,Immutability,我有以下当前状态。添加收件人时,新收件人应附加到默认数量为1的recipient.allIds和recipientProduct。我被困在recipientProduct部分的附加部分。这应该以不可变的方式来完成,因为这是一种redux状态 let currentState = { product: { allIds: ['1', '5'], }, recipient: { allIds: ['1'], }, recipientProduct: [{

我有以下
当前状态
。添加收件人时,新收件人应附加到默认数量为1的recipient.allIds和recipientProduct。我被困在
recipientProduct
部分的附加部分。这应该以
不可变的方式来完成,因为这是一种redux状态

let currentState = {
  product: {
    allIds: ['1', '5'],
  },
  recipient: {
    allIds: ['1'],
  },
  recipientProduct: [{
        recipientId: '1',
        productId: '1',
        qty: '3'
    }, {
        recipientId: '1',
        productId: '5',
        qty: '3'
    }],
};
附加新收件人时:

addRecipient = (recipientId) => {
    // when recipientId = 2
    // note quantity is always default to 1

    -> append productIds to product.allIds if not exists
    -> loop through all product from product.allIds
         loop through all recipient from recipient.allIds
         if (recipientId === recipientId && productId === productId) {
              remain
          } else {
            // append with default qty 1
        }

}
这将是
新闻状态

newstate = {
    product: {
        allIds: ['1', '5'],
    },
    recipient: {
        allIds: ['1', '2'],
    },
    recipientProduct: [{
        recipientId: '1',
        productId: '1',
        qty: '3'
    }, {
        recipientId: '1',
        productId: '5',
        qty: '3'
    },{
        recipientId: '2',
        productId: '1',
        qty: '1'
    }, {
        recipientId: '2',
        productId: '5',
        qty: '1'
    }],
}

您可以复制当前状态。请修改对象,然后再次将该对象指定给状态

addRecipient = (recipientId) => {
    let copy = {...currentState};
    copy.recipient.allIds.push(recipientId);
    copy.product.allIds.map((product)=>{
      let obj = {
        recipientId: recipientId,
        productId: product,
        qty: '1'
      }
      copy.recipientProduct.push(obj);
    });
    //Now `copy` is your new state.Old object will be as it is.
    //You can do anything with new object.
}
如果您使用的是redux,则可以调用action或setState并更改状态。
如果这对您有帮助,请告诉我。

您能试试这个逻辑吗

const redux=require(“redux”);
const createStore=redux.createStore;
const ADD_RECIPIENT=“ADD_RECIPIENT”;
常量初始状态={
产品:{
AllID:[“1”、“5”]
},
收件人:{
AllID:[“1”]
},
接收方产品:[
{
接收方ID:“1”,
productId:“1”,
数量:“3”
},
{
接收方ID:“1”,
productId:“5”,
数量:“3”
}
]
};
const reducer=(state=initialState,action)=>{
开关(动作类型){
案例添加收件人:
常量recipientId=action.recipientId;
const recipientExists=state.recipient.allIds.includes(recipientId);
如果(!recipientExists){
让recipientProducts=[…state.recipientProduct];
state.product.allIds.forEach(productId=>{
让产品存在=
state.recipientProduct.findIndex(r=>r.productId==productId)>-1;
让接受者存在=
state.recipientProduct.findIndex(r=>r.recipientId===recipientId)>-1;
如果(!productIdExists | |!recipientIdExists){
recipientProducts.push({recipientId,productId,数量:“1”});
}
});
返回{
……国家,
收件人:{
AllID:[…state.recipient.allID,recipientId]
},
recipientProduct:recipientProducts
};
}
返回状态;
违约:
返回状态;
}
};
const store=createStore(reducer);
store.subscribe(()=>{
console.log(“[newstate]”,store.getState());
});
仓库调度({
类型:添加收件人,
收件人ID:“2”
});

我认为它是一个应该处理所描述逻辑的缩减器,而不是一个动作创建者(?)
addRecipient

因此,据我所知,在公共Redux工作流中,您需要修改全局状态属性
recipient
(新收件人应被推入)和
recipientProduct
(对应于默认数量为1的每个产品的项目应被追加)在分派
APPEND\u recipient
操作或类似操作时

我的解决方案如下:

appReducer = (state=initialState, action) => {
        switch(action.type){
          case 'APPEND_RECIPIENT' : {
            let {payload: recipientId} = action,
                  {recipient:{allIds:recipientIds}, recipientProduct, product:{allIds:productIds}} = state
            if(recipientIds.includes(recipientId)) return state
            recipientIds = [...recipientIds, recipientId]
            recipientProduct = [...recipientProduct,...productIds.map(productId => ({productId, recipientId, qty: '1'}))]
            return {...state, recipient:{allIds:recipientIds}, recipientProduct}
          }
          default: return state
        }
      }
您可以在下面找到该概念的现场演示:

//依赖项
const{useState}=React,
{render}=ReactDOM,
{createStore}=Redux,
{connect,Provider}=ReactRedux
//初始状态、减速器和存储
const initialState={product:{allIds:['1','5']},recipientProduct:[{recipientId:'1',productId:'1',qty:'3'},{recipientId:'1',productId:'5',qty:'3'},
程序=(状态=初始状态,操作)=>{
开关(动作类型){
案例“附加收件人”:{
让{payload:recipientId}=action,
{recipient:{allIds:recipientIds},recipientProduct,product:{allIds:productIds}}}=state
if(recipientId.includes(recipientId))返回状态
recipientId=[…recipientId,recipientId]
recipientProduct=[…recipientProduct,…productId.map(productId=>({productId,recipientId,qty:'1'}))]
返回{…状态,收件人:{allIds:recipientIds},recipientProduct}
}
默认值:返回状态
}
},
store=createStore(Appeducer)
//附加收件人表单ui组件
常量AppendRecipient=({onAppendRecipient,onInput})=>{
常量[inputValue,setInput]=useState()
返回(
(e.preventDefault(),onAppendRecipient(inputValue))}>
setInput(e.target.value)}/>
)
}
//将AppendRecipient处理程序连接到分派“APPEND\u RECIPIENT”操作
const mapDispatchToProps=调度=>({
OnAppendRecipientId=>dispatch({type:'APPEND_RECIPIENT',负载:recipientId})
}),
AppendRecipientContainer=connect(null,mapDispatchToProps)(AppendRecipient)
//镜像接收方产品
const RecipientProducts=({products,productsQty})=>(
{
products.map({recipientId,productId,qty},key)=>收件人:{recipientId},产品:{productId},qty:{qty})
}
)
//将输出元素连接到全局recipientProducts
const-mapStateToProps=({recipientProduct})=>({products:recipientProduct,productsQty:recipientProduct.length}),
RecipientProductsContainer=connect(mapStateToProps)(RecipientProducts)
//呈现整个应用程序
渲染(
,
document.getElementById('root'))
)

您能解释一下为什么将此项
{recipientId:1 productId:'5',qty:'3'}
添加到recipientProduct吗?@YevgenGorbunkov有2个对象添加到
recipientProduct
,因为product.allId['1',5']中有2个productId。所以我需要把所有的
productId
都取回来,然后生成
{recipientId:'2',productId:'1',qty:'1'},{recipientId:'2',productId:'5',qty:'1'}
,它是productId 1的1,是productId 1的另一个5@YevgenGorbunkov你明白了吗?它是基于多收件人到多产品的标准化relationship@YevgenGorbunkov当我附加一个新的收件人时,你可以参考我在问题中提供的逻辑会话。@YevgenGorbunkov是的,你是对的。这是我的初始状态错误。我已经更新了它,以提供正确的