Магазин Redux не обновляет все изменения в app.js - PullRequest
0 голосов
/ 11 июня 2019

такая честь выпустить мой первый вопрос в этом сообществе! Я работаю над приложением рецептов, где я использую Redux для управления состояниями. Я использую асинхронное хранилище для локального хранения изменений. Я немного застрял сейчас, потому что мой магазин применяется только и хранит несколько изменений, а не весь рецепт.

Вот так выглядят данные рецепта (простите за мой голландский):

    {
  cardId: 2,
  time: "5 minutes",
  title: "Wortel-Kokossoep met Dadelroom",
  category: "ontbijt",
  image: require("./assets/wortel-kokossoep.jpg"),
  subtitle: "Gezonde en makkelijke soep!",
  caption: "Wortel-Kokossoep met Dadelroom",
  description:
    "Begin de dag gezond met deze smoothie dat rijk is aan vitamines.",
  stepOne: "Stap 1: Voeg alles toe aan de NutriBullet of blender.",
  stepTwo:
    "Stap 2: Blend twee keer gedurende ongeveer 5 tot 10 seconden en je bent klaar!",
  stepThree: "",
  stepFour: "",
  stepFive: "",
  stepSix: "",
  stepSeven: "",
  stepEight: "",
  favorite: false
},

и вот как я реализовал Redux в app.js. Пожалуйста, прости меня за размещение всего кода. Я все еще новичок, желающий узнать все о Redux и отреагировать.

    const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "FAV_RECIPIE":
      //const recipie = state.recipies.find(r => (r.cardId = action.id));
      const recipieIndex = state.recipies.findIndex(
        r => r.cardId === action.id
  );

  const currentValue = state.recipies[recipieIndex].favorite;
  state.recipies[recipieIndex].favorite = !currentValue;

  state.recipies = [...state.recipies];

  saveRecipes(state.recipies); // save to local storage
  return { ...state };

case "SET_LOADED_RECIPIES":
  console.warn("!!!!");
  if (action.recipies) {
    state.recipies = [...JSON.parse(action.recipies)]; // JSON parse to convert string back to list
  }
  console.log("set recipies");
  return { ...state };

case "OPEN_MENU":
  return { action: "openMenu" };
case "CLOSE_MENU":
  return { action: "closeMenu" };
default:
  return state;


 }
};

const saveRecipes = async recipies => {
  try {
    await AsyncStorage.setItem("@VV:Recipes", JSON.stringify(recipies)); // JSON stringify to convert list to string (for storage)
  } catch (error) {
    // error saving, and that is fine =)
    console.log("could not save recipes");



 }
};

const store = createStore(reducer, initialState);

store.subscribe(() => {
  console.log("store changed", store.getState().recipies);
});

const App = () => (
  <Provider store={store}>
    <AppNavigator />
  </Provider>
);

export default App;

Я действительно надеюсь, что некоторые из вас помогут мне! Заранее спасибо!

1 Ответ

1 голос
/ 11 июня 2019

В вашем редукторе есть пара неисправностей, но главное - мутации состояния.Вы хотите избежать логики, такой как:

state.recipies[recipieIndex].favorite = !currentValue;

также

state.recipies = [...state.recipies];

Это противоречит принципам избыточности.Вы никогда не захотите напрямую изменять значения состояния, не сделав сначала копию или клонирование.

Поэтому мы пойдем с созданием мелкой копии состояния в вашем редукторе и сделаем вместо этого обновления:

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "FAV_RECIPIE":
      var newState = {...state}
      //const recipie = state.recipies.find(r => (r.cardId = action.id));
      const recipieIndex = state.recipies.findIndex(
        r => r.cardId === action.id
      );

      const currentValue = state.recipies[recipieIndex].favorite;
      newState.recipies[recipieIndex].favorite = !currentValue;

      saveRecipes(newState.recipies); // save to local storage
      return { ...newState };

    case "SET_LOADED_RECIPIES":
      console.warn("!!!!");
      var newState = [...state]
      if (action.recipies) {
        newState.recipies = [...JSON.parse(action.recipies)]; // JSON parse to convert string back to list
      }
      console.log("set recipies");
      return { ...newState };

    case "OPEN_MENU":
      return { action: "openMenu" };
    case "CLOSE_MENU":
      return { action: "closeMenu" };
    default:
      return state;
  }
};

В качестве альтернативы мы можем сделать это кратко, используя .map (), который создает для нас копию.

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "FAV_RECIPIE":
      const updatedRecipes = {
        ...state,
        recipes: state.recipes.map(recipe => {
          if (recipe.cardId === action.id) {
            return {
              ...recipe,
              favorite: !recipe.favorite
            };
          } else {
            return recipe;
          }
        })
      };
      saveRecipes(updatedRecipes)
      return {
        ...updatedRecipes
      }
    case "SET_LOADED_RECIPIES":
      var newState = {...state};
      if (action.recipies) {
        newState.recipies = [...JSON.parse(action.recipies)]; // JSON parse to convert string back to list
      }
      return { ...newState };

    case "OPEN_MENU":
      return { action: "openMenu" };
    case "CLOSE_MENU":
      return { action: "closeMenu" };
    default:
      return state;
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...