简体   繁体   English

从 Redux 迁移到 Redux 工具包

[英]Migrating from Redux to Redux toolkit

I'm slowly migrating over from Redux to Redux toolkit.我正在慢慢地从 Redux 迁移到 Redux 工具包。 I'm still pretty new but I have this login action function.我还是个新手,但我有这个登录操作功能。 How can I translate old function below do I need createAsyncThunk to achieve this?我如何翻译下面的旧函数我需要createAsyncThunk来实现这个吗?

export const login = (email, password) => (dispatch) => {
  dispatch(requestLogin());
  firebase
    .auth()
    .signInWithEmailAndPassword(email, password)
    .then((user) => {
      dispatch(responseLogin(user));
    })
    .catch((error) => {
      dispatch(loginError());
    });
};

and my auth slice looks something like this:我的身份验证切片看起来像这样:

const authSlice = createSlice({
  name: "authSlice",
  initialState: {
    isLoggingIn: false,
    isLoggingOut: false,
    isVerifying: false,
    loginError: false,
    logoutError: false,
    isAuthenticated: false,
    user: {},
  },
  reducers: {
    signInWithEmail: (state, action) => {
      const { email, password } = action.payload;
      firebase
        .auth()
        .signInWithEmailAndPassword(email, password)
        .then((response) => {
          const {
            uid,
            email,
            emailVerified,
            phoneNumber,
            password,
            displayName,
            photoURL,
          } = response.user;
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
  extraReducers: {},
});

Lets create a productSlice.js让我们创建一个productSlice.js

import { createSlice,createSelector,PayloadAction,createAsyncThunk,} from "@reduxjs/toolkit";

export const fetchProducts = createAsyncThunk(
  "products/fetchProducts", async (_, thunkAPI) => {
     try {
        const response = await fetch(`url`); //where you want to fetch data
        return await response.json();
      } catch (error) {
         return thunkAPI.rejectWithValue({ error: error.message });
      }
});

const productsSlice = createSlice({
   name: "products",
   initialState: {
      products: [],
      loading: "idle",
      error: "",
   },
   reducers: {},
   extraReducers: (builder) => {
      builder.addCase(fetchProducts.pending, (state) => {
        state. products = [];
          state.loading = "loading";
      });
      builder.addCase(
         fetchProducts.fulfilled, (state, { payload }) => {
            state. products = payload;
            state.loading = "loaded";
      });
      builder.addCase(
        fetchProducts.rejected,(state, action) => {
            state.loading = "error";
            state.error = action.error.message;
      });
   }
});


export const selectProducts = createSelector(
  (state) => ({
     products: state.products,
     loading: state.products.loading,
  }), (state) =>  state
);
export default productsSlice;

In your store.js add productsSlice: productsSlice.reducer in out store reducer.在你的store.js添加productsSlice: productsSlice.reducer in out store reducer。

Then for using in component add those code ... I'm also prefer to use hook然后在组件中使用添加这些代码......我也更喜欢使用钩子

import { useSelector, useDispatch } from "react-redux";

import { fetchProducts,selectProducts,} from "path/productSlice.js";

Then Last part calling those method inside your competent like this然后最后一部分像这样在你的主管内部调用这些方法

const dispatch = useDispatch();
const { products } = useSelector(selectProducts);
React.useEffect(() => {
   dispatch(fetchProducts());
}, [dispatch]); 

And Finally, you can access data as products in your component.最后,您可以将数据作为组件中的products进行访问。

The reducer you showed is very wrong.你展示的减速器是非常错误的。 Reducers must never do anything async! Reducers绝不能做任何异步的事情

You don't need createAsyncThunk , but if you want to use it, it'd be like this:不需要createAsyncThunk ,但如果你使用它,它会是这样的:

export const login = createAsyncThunk(
  'login',
  ({email, password}) => firebase.auth().signInWithEmailAndPassword(email, password)
);

const authSlice = createSlice({
  name: "authSlice",
  initialState: {
    isLoggingIn: false,
    isLoggingOut: false,
    isVerifying: false,
    loginError: false,
    logoutError: false,
    isAuthenticated: false,
    user: {},
  },
  reducers: {
    /* any other state updates here */
  },
  extraReducers: (builder) => {
    builder.addCase(login.pending, (state, action) => {
      // mark something as loading here
    }

    builder.addCase(login.fulfilled, (state, action) => {
      // mark request as complete and save results
    }
  }
});

Note that createAsyncThunk only allows one argument to be passed to the thunk action creator, so it now must be an object with both fields instead of separate arguments.请注意, createAsyncThunk只允许将一个参数传递给 thunk 操作创建者,因此它现在必须是具有两个字段的对象,而不是单独的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM