Я ломаю голову, пытаясь понять структуру компонентов, которую я должен использовать. Я чувствую, что это то, что я абсолютно хочу получить правильно, потому что в будущем важно понять, как должно выглядеть приложение ReactJS и как правильно разделить проблемы. Я знаю, что это самоуверенный фронт, но то, как я сейчас это делаю, неверно, и я искал какую-то идею.
Модель данных: это большой набор рецептов, каждый из которых содержит другой набор ингредиентов. Я хочу позволить пользователю «пометить» (ингредиент удален из массива) ингредиентами, когда они их покупают / приобретают.
[
...
{
"title": "Recipe 1"
"ingredients": [
{ "title": "Flour", "measurement": "300g" },
{ "title": "Sesame Seeds", "measurement": "1 Tblsp" }
]
},
...
]
Текущее дерево компонентов Psuedo:
// RecipeList is my "HOC" (higher-order component) and contains all the functions/data required for the rest of the tree, and simply passes them down as props. This is `connect()`ed to the store here.
<RecipeList>
// Map on the highest level array to display a <Recipe> component for each
<Recipe data={recipe[mappedIndex]}>
// Map on each ingredient to create a list item for each
<RecipeIngredient data={recipe[mappedIndex].ingredient[mappedIndex]>
<IngredientCheckBox onChange={ //remove this ingredient from the array } />
</RecipeIngredient>
</Recipe>
</RecipeList>
Все хорошо с вышесказанным, данные отображаются именно так, как я и ожидал.
Однако, и это главная проблема , когда дело доходит до onChange
Я называю действие, COMPLETE_INGREDIENT
, которое в основном удаляет его из массива ingredients
(я вижу это в действии, используя redux-logger
, next-state
не содержит его).
К сожалению, мои компоненты не перерисовываются. Он больше не находится в массиве, но все еще отображается на экране. Я понимаю, что это может быть одной из следующих причин:
connect()
сравнивает только мелкие состояния, поэтому не запускает рендеринг, потому что это значение в массиве, внутри свойства объекта в массиве.
- Мой
connect()
слишком далек от действия и должен быть connect()
отредактирован на более глубоком уровне компонента, скажем, компонент <Recipe>
, и прикрепить его только к той части магазина, которая ему нужна (может даже быть <RecipeIngredient>
).
- Мой редуктор не изменяет состояние неизменным образом. Это тот, на котором я потратил больше всего времени, однако, даже используя
slice()
и все такое, я все равно не могу заставить его перерисовать
Редактировать: Мой редуктор для действия COMPLETE_INGREDIENT
. Я понимаю, что это может быть проблемой, так как это напрямую мутирует государство. Каков был бы правильный путь для такого глубокого изменения в государстве?
case COMPLETE_INGREDIENT:
// state is from a level above the recipe's, that contains a timestamp etc
state.recipes[action.payload.recipeIndex].ingredients.splice(action.payload.ingredientIndex, 1)
return Object.assign({
...state
})