首页 > 其他分享 >Redux 教程1 快速上手

Redux 教程1 快速上手

时间:2023-02-06 15:55:32浏览次数:36  
标签:教程 redux 数据 reducer 功能 action Redux 快速 store

  1. 文档翻译来的
  2. 用Typescript来的
  3. 不定期更新来的

环境配置,我看了一下,最好的配置方法是 npx create-react-app my-app --template redux-typescript

但问题是,我只是想在旧项目里添加redux。
我建议分两步走

  1. 旧项目用 Typescript基本模板 npx create-react-app my-app --template typescript
  2. 如果有需要,直接安装 react-redux @types/react-redux @reduxjs/toolkit ,注意,redux-toolkit已经包含了redux的 core。

快速开始

  1. 建立src/app/store.ts,并使用createStore建立 store、导出
import { configureStore } from "@reduxjs/toolkit";

const store= configureStore({
    reducer:{}
})

export default store

我的理解,store就是存储数据的仓库,这个仓库里的数据可以供App使用,为了把数据传递给App,需要使用到Provider ,这个Provider类似Context.

2.到index.tsx中,找到App ,用Provider包裹它。

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

刚才建立了仓库,并把仓库里的数据传递给App,但问题是store还是空的,下面丰富仓库内容。
3. 到src/features/counter/counterSlice.ts 建立一个功能(feature),因为说到底store管理数据,这个数据不是一成不变的,肯定是和某个功能挂钩,比如增加或者减少数据就是一个功能
注意,刚才的store在app中,现在又是一个新的文件夹feature,
关于为什么叫slice,我的理解是一个store存储很多数据,对应很多功能,不可能统一编写,而应该slice成不同切片,方便写和改。

一个slice 起码需要name来作为标识,需要initialState来初始化状态,需要一个或者多个reducer(函数)来执行具体功能。

这里有个事儿,旧版本的redux需要手动定义action,用action来告诉store具体执行什么功能,新版本的redux-toolkit里边提供的createSlice API把这个简化了,
提供上面说的参数,自动给你创建action creator。
还有一点,redux旧版本需要采取“不变”的写法,新版的createSlice和createReducer用了Immer.js,所以写“mutable”那种形式的状态变化就可以。

name:描述和区分这个切片的功能
initialState:有初始值
reducers:包含一个或多个函数,函数就是实现功能的东东

import { createSlice } from "@reduxjs/toolkit";

export const counterSlice = createSlice({
  name: "counter",
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
  initialState: { value: 0 },
});

// 每个reducer对应的action creators 在这里就能自动创建 ,一个action creator就是创建一个对象的函数
//action 就是个对象,里边包含了具体要执行什么操作,比如“ADD” "SUBTRACT",还包括了所属的slice的名字
/*
比如这个就是一个action
{
    "type": "counter/increment"
}
*/
export const { increment, decrement, incrementByAmount } = counterSlice.actions;


// 功能们
export default counterSlice.reducer;

好,现在store更丰富了,注意我们是从下向上地进行的操作,
store中肯定要包含数据和操作数据的功能,我们先通过slice的形式把数据和功能做好,随后加入到store即可。
通过在store的reducer中 以counter连接store和slice,因为之前说了name用于描述 还有 “区分”不同功能

app/store.ts

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice"
const store= configureStore({
    reducer:{
//注意 counterReducer传入以后,用store.getState()就能获取对应数据
        counter:counterReducer
    }
})

export default store

好,现在有个问题,我们刚才就在store中集成了功能和数据,那这个特定slice的数据呢?总不能每次都手动从一堆数据里边找吧?(因为store势必会变得很复杂)

简单, rtk提供了useSelector来快速的(通过slice名字)选取你所需要的数据的这么一条美好的捷径吖。

那么又怎么传递功能到UI上面呢?也简单,还是rtk提供了 useDispatch功能,只要执行action creator,把结果传给useDispatch执行生成的dispatch函数,就行。

好,现在只要把数据和功能 和UI绑定就行了。
features/counter/Counter.tsx

import React, { ReactElement } from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "../counter/counterSlice";
interface Props {}

export default function Counter({}: Props): ReactElement {
//数据,注意这个数据和slice中的name 是一致的
  const count = useSelector((state) => (state as any).counter.value);
//功能,就是发射action
  const dispatch = useDispatch();

  return (
    <div>
      <div>count是: {count}</div>
      <div
        onClick={() => {
          dispatch(increment());
        }}
      >
        +
      </div>
      <div
        onClick={() => {
          dispatch(decrement());
        }}
      >
        -
      </div>
    </div>
  );
}

以上,我们建立了仓库,通过切片组织了一个功能和初始数据,在UI中用RTK提供的工具拿到数据,并且可以通过dispatch执行功能。
action被执行后,就会dispatch到store,store调用对应的reducer,并对应更新数据,store中数据变化,UI就会知晓并重新渲染。

建立仓库使用rtk提供的configureStore,具体配置以对象形式填写,成员变量必须包括一个reducer对象。
通过Provider提供数据给App。
使用createSlice来创建功能的数据的 分片。(这样很利于形成separation of concerns)
因为rtk内置了Immerse.js,直接写mutable形式就行。
建立分片后,别忘记导出action creator和 对应的reducer。

在UI中,通过rtk提供的 useDispatch 和useSelector 来获取执行功能的dispatcher和抓取特定数据。

标签:教程,redux,数据,reducer,功能,action,Redux,快速,store
From: https://www.cnblogs.com/nulixuexipython/p/17095348.html

相关文章