首页 > 解决方案 > 减速器/动作不更新切片

问题描述

我显然遗漏了一些关于这应该如何工作的东西。我有一个切片,它有减速器,我可以把它们放进去,我可以看到 console.log 按预期触发...... buuut Redux 开发工具说我没有改变我的状态 - 默认 null 仍然是列出的值。

import { User } from "@firebase/auth";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

//Slice definition
// define state
interface UserState {
  currentUser: User | null;
}
const initialState: UserState = {
  currentUser: null,
};

//define action creators
const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {
    setUser(state, action: PayloadAction<User>) {
      state.currentUser = action.payload;
    },
    setNoUser(state) {
      state.currentUser = null;
    },
  },
});
//export all action creators
export const { setUser, setNoUser } = userSlice.actions;

//export reducer that handles all actions
export default userSlice.reducer;

店铺

import { configureStore } from "@reduxjs/toolkit";
import userReducer from "../features/user/user-slice";

export const store = configureStore({
  reducer: { user: userReducer },
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;

应用片段

import React, { useEffect, useState } from "react";
...
import { setUser, setNoUser } from "./features/user/user-slice";

function App() {
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    auth.onAuthStateChanged((user) => {
      if (user) {
        console.log("useEffect");
        console.log(user);
        setUser(user);
      } else {
        setNoUser();
        console.log("useEffect, no user");
      }
      setLoading(false);
    });
  });
  if (loading) return <Spinner animation="border" color="dark" />;
  return <App/>;
}

export default App;

标签: reactjsreact-redux

解决方案


这样做的原因是因为 setUser 是一个动作,并且需要调度该动作。

根据 Mark Erikson 的5 月视频,建议在使用打字稿时创建 useSelector 和 useDispatch 挂钩的类型化版本。

import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
import { RootState, AppDispatch } from "./store";

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const userAppSelector: TypedUseSelectorHook<RootState> = useSelector;

然后你从钩子文件中导入钩子而不是 react-redux 并从那里分派或选择:

const dispatch = useAppDispatch();
dispatch(setUser(auth.currentUser));

推荐阅读