最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 使用Redux Toolkit简化Redux

    正文概述 掘金(杭州程序员张张)   2021-04-07   582

    了解Redux Toolkit,这是用于高效Redux开发的经过验证的工具集。在本文中,你将看到为什么Redux Toolkit值得React社区更多的关注。

    React和Redux被认为是大规模React应用中管理状态的最佳组合。然而,随着时间的推移,Redux的受欢迎程度下降,原因是:

    • 配置Redux Store并不简单。
    • 我们需要几个软件包来使Redux与React一起工作。
    • Redux需要太多样板代码。

    带着这些问题,Redux的创建者Dan Abramov发表了名为《你可能不需要Redux》的文章,建议人们只在需要的时候使用Redux,而在开发不那么复杂的应用时,要遵循其他方法。

    Redux Toolkit解决的问题

    Redux Toolkit(之前称为Redux Starter Kit)提供了一些选项来配置全局store,并通过尽可能地抽象Redux API来更精简地创建动作和reducers。

    它包括什么?

    Redux Toolkit附带了一些有用的软件包,例如Immer,Redux-Thunk和Reselect。它使React开发人员的工作变得更加轻松,允许他们直接更改状态(不处理不可变性),并应用Thunk之类的中间件(处理异步操作)。它还使用了Redux的一个简单的“选择器”库Reselect来简化reducer函数。

    使用Redux Toolkit简化Redux

    Redux Toolkit API的主要功能?

    以下是Redux Took Kit使用的API函数,它是现有Redux API函数的抽象。这些函数并没有改变Redux的流程,只是以更易读和管理的方式简化了它们。

    • configureStore:像从Redux中创建原始的createStore一样创建一个Redux store实例,但接受一个命名的选项对象并自动设置Redux DevTools扩展。
    • createAction:接受一个Action类型字符串,并返回一个使用该类型的Action创建函数。
    • createReducer:接受初始状态值和Action类型的查找表到reducer函数,并创建一个处理所有Action类型的reducer。
    • createSlice:接受一个初始状态和一个带有reducer名称和函数的查找表,并自动生成action creator函数、action类型字符串和一个reducer函数。

    您可以使用上述API简化Redux中的样板代码,尤其是使用createActioncreateReducer方法。然而,这可以使用createSlice进一步简化,它可以自动生成action creator和reducer函数。

    createSlice有什么特别之处?

    它是一个生成存储片的助手函数。它接受片的名称、初始状态和reducer函数来返回reducer、action类型和action creators。

    首先,让我们看看在传统的React-Redux应用程序中reducers和actions的样子。

    Actions

    import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";
    export const GetUsers = (data) => (dispatch) => {
     dispatch({
      type: GET_USERS,
      payload: data,
     });
    };
    export const CreateUser = (data) => (dispatch) => {
     dispatch({
      type: CREATE_USER,
      payload: data,
     });
    };
    export const DeleteUser = (data) => (dispatch) => {
     dispatch({
      type: DELETE_USER,
      payload: data,
     });
    };
    

    Reducers

    import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";
    const initialState = {
     errorMessage: "",
     loading: false,
     users:[]
    };
    const UserReducer = (state = initialState, { payload }) => {
    switch (type) {
     case GET_USERS:
      return { ...state, users: payload, loading: false };
    case CREATE_USER:
      return { ...state, users: [payload,...state.users],
     loading: false };
    case DELETE_USER:
      return { ...state, 
      users: state.users.filter((user) => user.id !== payload.id),
    , loading: false };
    default:
      return state;
     }
    };
    export default UserReducer;
    

    现在,让我们看看如何使用createSlice简化并实现相同的功能。

    import { createSlice } from '@reduxjs/toolkit';
    export const initialState = {
      users: [],
      loading: false,
      error: false,
    };
    const userSlice = createSlice({
      name: 'user',
      initialState,
      reducers: {
        getUser: (state, action) => {
          state.users = action.payload;
          state.loading = true;
          state.error = false;
        },
        createUser: (state, action) => {
          state.users.unshift(action.payload);
          state.loading = false;
        },
        deleteUser: (state, action) => {
          state.users.filter((user) => user.id !== action.payload.id);
          state.loading = false;
        },
      },
    });
    export const { createUser, deleteUser, getUser } = userSlice.actions;
    export default userSlice.reducer;
    

    正如你所看到的,现在所有的动作和reducer都在一个简单的地方,而在传统的redux应用中,你需要在reducer中管理每一个action和它对应的action,当使用createSlice时,你不需要使用开关来识别action。

    当涉及到突变状态时,一个典型的Redux流程会抛出错误,你将需要特殊的JavaScript策略,如spread operator和Object assign来克服它们。由于Redux Toolkit使用Immer,因此您不必担心会改变状态。由于slice创建了actionsreducers,你可以导出它们,并在你的组件和Store中使用它们来配置Redux,而无需为actionsreducers建立单独的文件和目录,如下所示。

    import { configureStore } from "@reduxjs/toolkit";
    import userSlice from "./features/user/userSlice";
    export default configureStore({
     reducer: {
      user: userSlice,
     },
    });
    

    这个存储可以通过使用useSelectoruseDispatch的redux api直接从组件中使用。请注意,您不必使用任何常量来标识操作或使用任何类型。

    处理异步Redux流

    为了处理异步动作,Redux Toolkit提供了一个特殊的API方法,称为createAsyncThunk,它接受一个字符串标识符和一个payload创建者回调,执行实际的异步逻辑,并返回一个Promise,该Promise将根据你返回的Promise处理相关动作的调度,以及你的reducers中可以处理的action类型。

    import axios from "axios";
    import { createAsyncThunk } from "@reduxjs/toolkit";
    export const GetPosts = createAsyncThunk(
    "post/getPosts", async () => await axios.get(`${BASE_URL}/posts`)
    );
    export const CreatePost = createAsyncThunk(
    "post/createPost",async (post) => await axios.post(`${BASE_URL}/post`, post)
    );
    

    与传统的数据流不同,由createAsyncThunk处理的action将由分片内的extraReducers部分处理。

    import { createSlice } from "@reduxjs/toolkit";
    import { GetPosts, CreatePost } from "../../services";
    export const initialState = {
      posts: [],
      loading: false,
      error: null,
    };
    export const postSlice = createSlice({
    name: "post",
    initialState: initialState,
    extraReducers: {
       [GetPosts.fulfilled]: (state, action) => {
         state.posts = action.payload.data;
       },
       [GetPosts.rejected]: (state, action) => {
        state.posts = [];
       },
       [CreatePost.fulfilled]: (state, action) => {
       state.posts.unshift(action.payload.data);
       },
     },
    });
    export default postSlice.reducer;
    

    请注意,在extraReducers内部,您可以处理已解决(fulfilled)和已拒绝(rejected)状态。

    通过这些代码片段,您可以看到此工具包在Redux中简化代码的效果如何。我创建了一个利用Redux Toolkit的REST示例供您参考。

    最后的想法

    根据我的经验,当开始使用Redux时,Redux Toolkit是一个很好的选择。它简化了代码,并通过减少模板代码来帮助管理Redux状态。

    最后,就像Redux一样,Redux Toolkit并非仅为React构建。我们可以将其与其他任何框架(例如Angular)一起使用。

    您可以通过参考Redux Toolkit的文档找到更多信息。

    谢谢您的阅读!


    翻译自blog.bitsrc.io,作者:Madushika Perera

    更多文章

    • Rust与Python:为什么Rust可以取代Python
    • 使用RoughViz可视化Vue.js中的草绘图表
    • 编程日历小程序,对小程序云开发和生成分享海报的实践
    • 改善应用程序性能和代码质量:通过代理模式组合HTTP请求
    • [译]面向对象编程是计算机科学的最大错误
    • 译|使HTML 5数字输入仅接受整数
    • 13个顶级免费所见即所得文本编辑器工具

    下载网 » 使用Redux Toolkit简化Redux

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元