создание редуктора для вложенного массива объектов - PullRequest
0 голосов
/ 05 июня 2018

Я провел два дня, пытаясь создать редуктор, который изменяет логическое значение для свойства toRecipe, но безуспешно.Это вложенный массив объектов.Я не могу двигаться вперед с этим, это структура массива:

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:Не удается прочитать свойство 'c' из неопределенного

Я перечисляю этот массив здесь (жирный текст):

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>
    )
  }
}

Может ли кто-нибудь мне помочь?

1 Ответ

0 голосов
/ 05 июня 2018
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 undefined.Чтобы заставить его работать так, вам нужно предварительно проверить, существует ли он как

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, например, и оно будет работать лучше, и не будет такой сумасшедшей логики, как указано выше.

...