RTK(二代redux)和一代redux的对比学习

说明

RTK是在原有的redux基础上进行了二次封装,提供开箱即用的API,所以更像是他的一个类库。

对比来理解,他们俩一个像是js,另一个则像是jQuery。所以为什么不使用jQuery(RTK)来开发,上手简单。

Tips:对比redux学习是为了更好的理解RTK是怎么对redux进行封装的。

1,安装核心依赖包

redux

安装:npm install redux

// 依赖包示例:"redux": "2.3"

RTK

安装:npm install @reduxjs/toolkit

// 依赖包实例:"@reduxjs/toolkit": "^1.9.7"

2,定义状态和reducer函数

redux

分别定义state状态和reducer函数,reducer函数接收当前的state和action对象。

// 定义初始状态
const initialState = {
  count: 0,
};

// 编写reducer函数
function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'incremented':
      return { value: state.count + 1 }
    case 'decremented':
      return { value: state.count - 1 }
    default:
      return state
  }
}

RTK

利用createSlice切片来简化action和reducer的创建,在createSlice中定义reducers对象,每个键值对代表一个action类型和对应的reducer函数。

一个createSlice切片可以理解为一个业务模块。

// 引入创建slice切片的函数
import { createSlice } from '@reduxjs/toolkit';

// 创建一个切片,传入name、初始值、reducers函数
// createSlice是对createAction和createReducer的包装和更高层的抽象
const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment(state) {
      state.count += 1;
    },
    decrement(state) {
      state.count -= 1;
    },
  },
});

3,创建store

redux

使用createStore函数。这个函数接受一个reducer函数作为参数,并返回一个新的Store对象。

// 引入创建store的函数
import { createStore } from 'redux'

// 用reducer作为参数创建store
let store = createStore(counterReducer)

RTK

使用configureStore函数替代createStore,将创建的切片对象的reducer属性作为参数传入,RTK 自动处理 Reducer 的合并。

// 引入创建store的函数
import { configureStore } from '@reduxjs/toolkit'


// 通过将切片.reducer函数作为参数,创建store
const store = configureStore({
  reducer: counterSlice.reducer
})

4,dispatch派发action和subscribe订阅

redux

订阅:通过store.subscribe方法来实现订阅。

分发:通过store.dispatch方法来实现分发,传入action

// store通过subscribe订阅
store.subscribe(() => console.log(store.getState()))

// 调用store的dispatch方法改变state
store.dispatch({ type: 'increment' })
// {count: 1}
store.dispatch({ type: 'decrement' })
// {count: 1}

RTK: 

订阅:也是通过store.subscribe方法来实现订阅。

分发:通过store.dispatch方法来实现分发,他传入的action通过切片对象的actions属性来解构获取

// store通过subscribe订阅
store.subscribe(() => console.log(store.getState()))

// 通过创建的切片counterSlice.actions解构获得各个reducer函数
export const { increment, decrement } = counterSlice.actions;

// 调用store的dispatch方法改变state
store.dispatch(increment())
// {count: 1}
store.dispatch(decrement ())
// {count: 1}

5,创建 Selectors

Selectors 是函数,用于从 state 中选择数据。

RTK提供了createSelector函数,用于创建可缓存的selectors,以提高性能。

createSelector函数提供了 memoization 功能,这意味着如果传入的参数没有变化,它会返回缓存的结果,而不是重新计算。

使用selectors可以轻松地从state中获取数据,而无需担心如何正确地引用和更新 state。

redux

手动编写选择器函数。

// Redux 选择器函数
function selectCount(state) {
  return state.count;
}

const currentValue = selectCount(store.getState());

RTK

使用createSelector函数创建一个 selector函数,该函数接收 state 作为参数,并返回所需的数据片段。

// RTK 选择器函数,counter是切片的name
export const selectCount = (state) => state.counter.count;

6,使用trunk分发异步action

redux

需要引入redux-trunk中间件,然后手动编写async/await逻辑处理异步操作,并且手动派发三种不同的 action 来表示异步操作的不同阶段:开始pending、成功fulfilled和失败rejected

// 定义action creators
export const fetchDataBegin = () => ({
  type: 'FETCH_DATA_BEGIN',
});

export const fetchDataSuccess = (data) => ({
  type: 'FETCH_DATA_SUCCESS',
  payload: data,
});

export const fetchDataFailure = (error) => ({
  type: 'FETCH_DATA_FAILURE',
  payload: error,
});

// redux-thunk进行异步action的分发
export const fetchData = () => async (dispatch) => {
  dispatch({ type: 'FETCH_DATA_BEGIN' });
  try {
    const response = await fetch('/api/data');
    const data = await response.json();
    dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
  } catch (error) {
    dispatch({ type: 'FETCH_DATA_FAILURE', payload: error });
  }
};

在组件中调用接口函数

// 组件中调用接口
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { fetchData } from './actions';

const MyComponent = () => {
  const dispatch = useDispatch();

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

  return (
    <div>
      {/* 显示组件内容 */}
    </div>
  );
};

export default MyComponent;

RTK

内置了redux-trunk中间件,调用createAsyncThunk函数来实现,只返回一个promise,RTK会自动处理promise的三种状态。他会为你生成三个特殊的action类型:[type]/pending、[type]/fulfilled 和 [type]/rejected。这些特殊的action类型对应于异步操作的三个阶段。当然在组件中,可以使用useSelector钩子来访问这些状态。

// 引入createAsyncThunk函数
import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchData = createAsyncThunk('fetchData', async () => {
  const response = await fetch('/api/data');
  const data = await response.json();
  return data;
});

在组件中调用接口函数,同时在组件中用useSelector钩子访问这些状态

// 组件中调用接口,基本相同
import ......
import { useSelector } from 'react-redux';
// ...

  useEffect(() => {
    dispatch(fetchData());
  }, [dispatch, count]); // 这里会有不同

// ...

// 在组件中用useSelector钩子访问这些状态
const userFetchStatus = useSelector((state) => state.user.fetch.status);
const user = useSelector((state) => state.user.fetch.fulfilled);

switch (userFetchStatus) {
  case 'pending':
    return <p>Loading...</p>;
  case 'fulfilled':
    return <p>User fetched successfully: {JSON.stringify(user)}</p>;
  case 'rejected':
    return <p>Failed to fetch user: {userFetchStatus.error}</p>;
  default:
    return null;
}

export default MyComponent;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妍思码匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值