refactoring from createStore (Redux) to configureStore(RTK) leads to doubtfull situation or even error when enhancers are applied

huangapple go评论76阅读模式
英文:

refactoring from createStore (Redux) to configureStore(RTK) leads to doubtfull situation or even error when enhancers are applied

问题

因为VS Code建议,我决定尝试重写现有的代码以使用configureStore。

重构之前(是的,reducer被采用"as it is",我知道应该使用combineReducers,但这时我只有一个reducer来处理整个状态):

declare module "@mui/styles/defaultTheme" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}
const composeEnhancers = process.env.NODE_ENV === "production" ? compose : composeWithDevTools({});
export const store = createStore(reducer, composeEnhancers(applyMiddleware(thunkMiddleware)));
const AppProvider: FC = ({ children }) => {
  return (
    <Provider store={store}>
      <QueryClientProvider client={useQueryClient()}>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: "bottom",
                horizontal: "center",
              }}
            >
              <PlaceContextProvider>
                <CheckSupportForLocalStorage>
                  <CheckSupportForGeolocation>
                    <SetBackground>
                      <Router>{children}</Router>
                    </SetBackground>
                  </CheckSupportForGeolocation>
                </CheckSupportForLocalStorage>
              </PlaceContextProvider>
            </SnackbarProvider>
          </ThemeProvider>
        </StyledEngineProvider>
      </QueryClientProvider>
    </Provider>
  );
};

重构后,但不工作:

declare module "@mui/styles/defaultTheme" {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}

const composeEnhancers = process.env.NODE_ENV === "production" ? compose : composeWithDevTools({});
export const store = configureStore({ reducer, enhancers: [composeEnhancers] });
const AppProvider: FC = ({ children }) => {
  return (
    <Provider store={store}>
      <QueryClientProvider client={useQueryClient()}>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: "bottom",
                horizontal: "center",
              }}
            >
              <PlaceContextProvider>
                <CheckSupportForLocalStorage>
                  <CheckSupportForGeolocation>
                    <SetBackground>
                      <Router>{children}</Router>
                    </SetBackground>
                  </CheckSupportForGeolocation>
                </CheckSupportForLocalStorage>
              </PlaceContextProvider>
            </SnackbarProvider>
          </ThemeProvider>
        </StyledEngineProvider>
      </QueryClientProvider>
    </Provider>
  );
};

它能够编译,但会抛出运行时错误:"Uncaught Error: Expected the reducer to be a function." 我相信我按照这个模式操作:https://redux-toolkit.js.org/api/configureStore

像这样添加enhancers有什么问题?

英文:

because of VS Code suggestions, I decided to try to rewrite existing code to the one with configureStore.

Before refactor (yes, reducer is taken "as it is", I know that should use combineReducers; but at this time I have one reducer with whole state):

declare module &quot;@mui/styles/defaultTheme&quot; {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}
const composeEnhancers = process.env.NODE_ENV === &quot;production&quot; ? compose : composeWithDevTools({});
export const store = createStore(reducer, composeEnhancers(applyMiddleware(thunkMiddleware)));
const AppProvider: FC = ({ children }) =&gt; {
  return (
    &lt;Provider store={store}&gt;
      &lt;QueryClientProvider client={useQueryClient()}&gt;
        &lt;StyledEngineProvider injectFirst&gt;
          &lt;ThemeProvider theme={theme}&gt;
            &lt;SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: &quot;bottom&quot;,
                horizontal: &quot;center&quot;,
              }}
            &gt;
              &lt;PlaceContextProvider&gt;
                &lt;CheckSupportForLocalStorage&gt;
                  &lt;CheckSupportForGeolocation&gt;
                    &lt;SetBackground&gt;
                      &lt;Router&gt;{children}&lt;/Router&gt;
                    &lt;/SetBackground&gt;
                  &lt;/CheckSupportForGeolocation&gt;
                &lt;/CheckSupportForLocalStorage&gt;
              &lt;/PlaceContextProvider&gt;
            &lt;/SnackbarProvider&gt;
          &lt;/ThemeProvider&gt;
        &lt;/StyledEngineProvider&gt;
      &lt;/QueryClientProvider&gt;
    &lt;/Provider&gt;
  );
};

After refactor, not working

declare module &quot;@mui/styles/defaultTheme&quot; {
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface DefaultTheme extends Theme {}
}

const composeEnhancers = process.env.NODE_ENV === &quot;production&quot; ? compose : composeWithDevTools({});
export const store = configureStore({ reducer, enhancers:[composeEnhancers] });
const AppProvider: FC = ({ children }) =&gt; {
  return (
    &lt;Provider store={store}&gt;
      &lt;QueryClientProvider client={useQueryClient()}&gt;
        &lt;StyledEngineProvider injectFirst&gt;
          &lt;ThemeProvider theme={theme}&gt;
            &lt;SnackbarProvider
              maxSnack={3}
              anchorOrigin={{
                vertical: &quot;bottom&quot;,
                horizontal: &quot;center&quot;,
              }}
            &gt;
              &lt;PlaceContextProvider&gt;
                &lt;CheckSupportForLocalStorage&gt;
                  &lt;CheckSupportForGeolocation&gt;
                    &lt;SetBackground&gt;
                      &lt;Router&gt;{children}&lt;/Router&gt;
                    &lt;/SetBackground&gt;
                  &lt;/CheckSupportForGeolocation&gt;
                &lt;/CheckSupportForLocalStorage&gt;
              &lt;/PlaceContextProvider&gt;
            &lt;/SnackbarProvider&gt;
          &lt;/ThemeProvider&gt;
        &lt;/StyledEngineProvider&gt;
      &lt;/QueryClientProvider&gt;
    &lt;/Provider&gt;
  );
};


its compiles but throws runtime error:Uncaught Error: Expected the reducer to be a function. I believed I follow this pattern: https://redux-toolkit.js.org/api/configureStore

What is wrong with adding enhancers like this?

答案1

得分: 1

通常,devToolsthunk 是默认中间件的一部分 - 如果你想添加中间件,应该使用 middleware 选项,而不是 enhancers 选项。

所以在你的情况下,

export const store = configureStore({ reducer });

已经配置了 devToolsthunk 中间件,你不需要再做其他操作。

不幸的是,你展示的片段不是有效的JavaScript(缺少一个 ] 以便解释),而且你将一个 composeEnhancers 函数传递进了那个函数中,而不是一个增强器本身(通常也不应该使用数组符号,因为这会覆盖所有默认的增强器)。

如果没有展示导致此错误的真正代码,很难提供更多关于问题具体原因的反馈。

英文:

Generally, devTools and thunk are part of the default middleware - and if you want to add middleware, you should do so using the middleware option, not the enhancers option.

So in your case,

export const store = configureStore({ reducer });

already has the devTools and the thunk middleware configured, nothing more to do on your side.

Unfortunately, the snippet you are showing up there is not valid JavaScript (missing a ] to be interpretable), and you are passing a composeEnhancers function, not an enhancer itself into that function (and should generally probably also not use the array notation, as that overwrites all the default enhancers).

Without showing the code that really caused this error, it's hard to give more feedback on what exactly is causing you problems there.

huangapple
  • 本文由 发表于 2023年7月10日 20:30:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定