首页 > 解决方案 > 为嵌套的对象数组创建reducer

问题描述

我花了两天时间尝试创建reducer,它将属性的布尔值更改为Recipe,但没有成功。这是嵌套的对象数组。我无法继续前进,这是数组的结构:

recipes: [ 
               { id: int, 
                 re: 'string',
                 c: [ 
                                  { id: int,
                                    co: 'string',
                                    toRecipe: false
                                  },
                                  {...}
                              ]
               },
               {...}
            ]

我创建了一个这样的减速器:

case actionTypes.EDIT_BOOLEAN:
  return {
    ...state,
    recipes: {...state.recipes,
    [action.payload.idFromRecipe]: {...state.recipes[action.payload.idFromRecipe],
    c: {...state.recipes[action.payload.idFromRecipe].c,
    [action.payload.idFromComp]: {...state.recipes[action.payload.idFromRecipe].c[action.payload.idFromComp], toRecipe: false}
  }
  }
  }
}

但是当我使用这个减速器时出现错误:TypeError: Cannot read property 'c' of undefined

我在这里列出了这个数组(粗体字):

class RecipeList extends Component {

  render(){

    console.log(this.props.recipes.map(recipe=>recipe));
    let compons = this.props.recipes.map(recipe =>(
            <div key={recipe.id}>
            <h2>{recipe.re}</h2>
              <ul key={recipe.id}>
              {recipe.c.map(comp=> comp.toRecipe === true ?
                <li key={comp.id}>{comp.co}</li>
                : null
              )}
              </ul>
              <div>
                <form>
                 **{ recipe.c.map((comp, i)=>(
                  <div key={i}>
                <input
                  onChange={()=>this.props.editRecipes(comp.id,recipe.id)}
                  type="checkbox"
                  key={i}
                  checked={comp.toRecipe}
                />
                <label key={comp.id}>{comp.co}</label>

                </div>
              ))  }**
                </form>

              </div>
            </div>
      )
    );
    console.log(compons);
    return (
      <div>
        {compons}

      </div>
    )
  }
}

有人可以帮我吗?

标签: javascriptreactjsreduxreducers

解决方案


You are trying to access property that doesn't exist yet

    return {
        ...state,
        recipes: {
            ...state.recipes,
            [action.payload.idFromRecipe]: {
                ...state.recipes[action.payload.idFromRecipe],
                c: {
                    ...state.recipes[action.payload.idFromRecipe].c,
                    [action.payload.idFromComp]: {
                        ...state.recipes[action.payload.idFromRecipe].c[action.payload.idFromComp],
                        toRecipe: false
                    }
                }
            }
        }
    };

所以基本上让我们举一个例子,你试图让嵌套对象工作。您的操作有有效载荷,即 idFromRecipe = "123",

are you entirely sure that state.recipes.123.c exist? because it seems like it doesn't so it returns undefined so lane  

     ...state.recipes[action.payload.idFromRecipe].c,

将失败,因为您无法访问未定义的属性 C。为了使它像那样工作,您需要事先检查它是否存在

c: state.recipes[action.payload.idFromRecipe] ? {
   ...state.recipes[action.payload.idFromRecipe].c,
                [action.payload.idFromComp]: {
                    ...state.recipes[action.payload.idFromRecipe].c[action.payload.idFromComp],
                    toRecipe: false
                }
} : {
                      ...state.recipes[action.payload.idFromRecipe].c[action.payload.idFromComp],
                    toRecipe: false
                }
}

通常你应该避免这种构造,因为之后的逻辑非常奇怪和优化问题(因为你几乎每次都需要更改整个对象)。我的建议是实际上用 normalizr 规范化状态,例如,它会更好地工作,并且不会有像上面那样疯狂的逻辑。


推荐阅读