Redux存储不会更新app.js中的所有更改

时间:2019-06-11 18:28:34

标签: reactjs react-redux

很荣幸在这个社区中提出我的第一个问题!我正在使用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
},

,这就是我在app.js中实现Redux的方式。请原谅我发布了整个代码。我仍然是菜鸟,渴望学习有关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 个答案:

答案 0 :(得分:1)

Reducer中有几处错误,但是重要的是进行状态更改。您想避免类似

的逻辑
state.recipies[recipieIndex].favorite = !currentValue;

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

这违反了redux原则。您永远都不想直接更改状态的值而无需先进行复制或克隆。

因此,我们将在化简器中创建状态的浅表副本,并对其进行更新:

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