Formik 值未保存在 redux 持久切片中

问题描述 投票:0回答:1
store:
import { configureStore } from "@reduxjs/toolkit";

//SLICES
import mainLayoutReducer from "./mainLayoutSlice";
import userDataReducer from "./userDataSlice";
import schedulePeriodReducer from "./schedulePeriodSlice";
import loadingReducer from "./loadingSlice";
import draftDataSlice from "./draftDataSlice";

// API
import { tmsApi } from "../api";
import { daDataApi } from "../api/thirdPartyApis/daDataApi";

import {
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from "redux-persist";

import storage from "redux-persist/lib/storage";

const persistConfig = {
  key: "root",
  storage,
};

const persistedMainLayoutReducer = persistReducer(
  persistConfig,
  mainLayoutReducer
);

const persistedDraftReducer = persistReducer(
  persistConfig,
  draftDataSlice
);

const persistedLoadingReducer = persistReducer(persistConfig, loadingReducer);

const store = configureStore({
  reducer: {
    //PERSISTED SLICES
    mainLayout: persistedMainLayoutReducer,
    loading: persistedLoadingReducer,
    draftData: persistedDraftReducer,
    // schedulePeriod: persistedSchedulePeriodReducer,

    //SLICES
    userData: userDataReducer,
    schedulePeriod: schedulePeriodReducer,

    //API
    [tmsApi.reducerPath]: tmsApi.reducer,
    [daDataApi.reducerPath]: daDataApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    })
      .concat(tmsApi.middleware)
      .concat(daDataApi.middleware),
});

export default store;

slice:
import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  draftData: null,
};

export const draftDataSlice = createSlice({
  name: "draftData",
  initialState,
  reducers: {
    setDraftData: (state, action) => {
      state.draftData = action.payload;
    },
    clearDraftData: (state) => {
      state.draftData = null;
    },
  },
});

export const { setDraftData, clearDraftData } = draftDataSlice.actions;

export default draftDataSlice.reducer;


in component:

 const isDraft = location.search;
 const draftData = useSelector((state) => state.draftData.draftData);

const formik = useFormik({
    initialValues: isDraft
      ? draftData
      : {
          ...mainInfoValues(employeeInfo),
          ...vehicleInfoValues(employeeInfo),
          ...docsValues(employeeInfo),
        },
onSubmit: //here onSubmit func
)}

 useEffect(() => {
     dispatch(setDraftData(values));
    }, [values]);

return(
  <form onSubmit={handleSubmit}>
            <Section overflow="inherit">
              {(() => {
                switch (step) {
                  case 1:
                    return (
                      <MainInfo
                        values={values}
                        handleChange={handleChange}
                        setFieldValue={setFieldValue}
                        setValues={setValues}
                        touched={touched}
                        errors={errors}
                        handleBlur={handleBlur}
                        isStepOneEmpty={isStepOneEmpty}
                        resetForm={resetForm}
                        handleStep={handleStep}
                      />
                    );
                  case 2:
                    return (
                      <VehicleInfo
                        values={values}
                        handleChange={handleChange}
                        setFieldValue={setFieldValue}
                        setValues={setValues}
                        touched={touched}
                        errors={errors}
                        handleBlur={handleBlur}
                        isStepTwoEmpty={isStepTwoEmpty}
                        resetForm={resetForm}
                        handleStep={handleStep}
                      />
                    );
                  case 3:
                    return (
                      <AttachDocs
                        values={values}
                        handleChange={handleChange}
                        setFieldValue={setFieldValue}
                        setValues={setValues}
                        touched={touched}
                        errors={errors}
                        handleBlur={handleBlur}
                        isStepThreeEmpty={isStepThreeEmpty}
                        resetForm={resetForm}
                        handleStep={handleStep}
                      />
                    );

                  default:
                    break;
                }
              })()}
            </Section>
          </form>
)

我正在尝试将 formik 中的值保存到持久切片中,一切正常,直到重定向到另一个页面并刷新它。当我回来时,我的切片是空的,但是如果用表单刷新当前页面,一切正常并且切片不为空。

步骤:

  1. 在表单中对值进行一些更改
  2. 切片完整
  3. 重定向到另一个页面
  4. 刷新页面
  5. 返回表格页面
  6. 切片为空
redux formik redux-persist
1个回答
0
投票

问题

我认为问题在于您的持久化减速器都使用相同的持久性

key
属性,因此它们最终会相互覆盖。

const persistConfig = {
  key: "root", // <-- key => "persist:root"
  storage,
};

const persistedMainLayoutReducer = persistReducer(
  persistConfig, // <-- key <= "persist:root"
  mainLayoutReducer
);

const persistedDraftReducer = persistReducer(
  persistConfig, // <-- key <= "persist:root"
  draftDataSlice
);

const persistedLoadingReducer = persistReducer(
  persistConfig, // <-- key <= "persist:root"
  loadingReducer
);

解决方案建议

为每个切片减速器使用单独的持久性密钥

const rootPersistConfig = {
  key: "root", // <-- key => "persist:root"
  storage,
};

const persistedMainLayoutReducer = persistReducer(
  rootPersistConfig, // <-- key <= "persist:root"
  mainLayoutReducer
);

const draftPersistConfig = {
  key: "draft", // <-- key => "persist:draft"
  storage,
};

const persistedDraftReducer = persistReducer(
  draftPersistConfig, // <-- key <= "persist:draft"
  draftDataReducer
);

const loadingPersistConfig = {
  key: "loading", // <-- key => "persist:loading"
  storage,
};

const persistedLoadingReducer = persistReducer(
  loadingPersistConfig, // <-- key <= "persist:loading"
  loadingReducer
);

const store = configureStore({
  reducer: {
    // PERSISTED SLICES
    mainLayout: persistedMainLayoutReducer,
    loading: persistedLoadingReducer,
    draftData: persistedDraftReducer,
    // schedulePeriod: persistedSchedulePeriodReducer,

    // SLICES
    userData: userDataReducer,
    schedulePeriod: schedulePeriodReducer,

    // API
    [tmsApi.reducerPath]: tmsApi.reducer,
    [daDataApi.reducerPath]: daDataApi.reducer,
  },
  ...
});

使用单一持久化配置并将您想要持久化的减速器列入白名单/黑名单。

const rootReducer = combineReducers({
  // PERSISTED SLICES
  mainLayout: mainLayoutReducer,
  loading: loadingReducer,
  draftData: draftDataReducer,
  // schedulePeriod: schedulePeriodReducer,

  // SLICES
  userData: userDataReducer,
  schedulePeriod: schedulePeriodReducer,

  // API
  [tmsApi.reducerPath]: tmsApi.reducer,
  [daDataApi.reducerPath]: daDataApi.reducer,
});

const persistConfig = {
  key: "root",
  storage,
  // Only persist these root reducers
  whitelist: ["mainLayout", "loading", "draftData"],
};

const persistedRootReducer = persistReducer(
  persistConfig,
  rootReducer
);

const store = configureStore({
  reducer: persistedRootReducer,
  ...
});
© www.soinside.com 2019 - 2024. All rights reserved.