Redux从简单到进阶(Redux、React-redux、Redux-toolkit)

一、Redux

1.1 Redux 作用

Redux 是一个 JavaScript 状态管理库,主要用于管理应用的状态并确保状态的一致性和可预测性。Redux 采用了单一数据源 的概念,即整个应用的状态被存储在一个 JavaScript 对象树中,通过一个统一的 store 管理。应用的状态只能通过触发 action 来改变,所有的状态更新逻辑都放在 reducer 函数中。Redux 的核心思想是 单向数据流,使得应用的状态变化更加可控和可预测。

1.1 Redux安装
复制代码
npm install redux
1.2 Redux使用方式
  1. 定义一个 reducer 函数(根据当前想要做的修改返回一个新的状态)
  2. 使用 createStore 方法传入 reducer 函数,生成一个 Store 实例对象
  3. 使用 Store 实例的 subscribe 方法订阅数据的变化(监听数据变化,数据一旦变化,可以得到通知)
  4. 使用 Store 实例的 dispatch 方法提交 action 对象,触发数据变化(告诉 reducer 你想怎么改数据)
  5. 使用 Store 的 getState 方法获取最新的状态数据更新到视图中
1.3 Redux使用示例
1.创建 Store
go 复制代码
import { createStore } from 'redux'

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

// 1.定义reducer函数
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 }
    case 'DECREMENT':
      return { count: state.count - 1 }
    default:
      return state
  }
}

// 2.使用reducer函数生成Store实例
const store = createStore(reducer)
2.触发 action
javascript 复制代码
const [count, setCount] = useState(store.getState().count)

// 3.通过Store实例的subscribe订阅(监听)数据变化
store.subscribe(() => {

    // 5、通过Store实例的getState方法获取最新的state
    setCount(store.getState().count)

})
  
// 4、通过Store实例的dispatch函数提交action更改状态
  const handleAdd = () => store.dispatch({ type: 'INCREMENT' })
  const handleSub = () => store.dispatch({ type: 'DECREMENT' })


<div>
    <button onClick={handleAdd}>+</button>
    <div>{count}</div>
    <button onClick={handleSub}>-</button>
</div>

二、React-Redux

1、React-Redux是什么

在学习了 react 之后,紧接着,我们学习了 redux 。那如果把它们俩结合起来, react-redux 是什么呢?实际上,它是一个第三方模块,它使得我们在 react 中更加方便地使用 redux

2、React-Redux的使用
2.1 安装React-Redux
复制代码
npm install react-redux
2.2 React-Redux使用示例
1.创建Store
javascript 复制代码
import { createStore } from "redux";

const initState = { count: 0 };

const reducer = (state = initState, action) => {
  switch (action.type) {
    case "add_action":
      return { count: state.count + 1 };
    case "sub_action":
      return { count: state.count - 1 };
    default:
      return state;
  }
}
const store = createStore(reducer);

export default store;
2.搭建页面结构
  • 创建一个组件名为Btn,里放一个button按钮

  • 另创一个组件名为Counter,用来显示数字

3.在app.jsx导入Provider组件
javascript 复制代码
import { Provider } from 'react-redux'
4.利用Provider组件将我们整个结构进行包裹,并且传递Store
xml 复制代码
<Provider store={store}>
  <div>
    ...
  </div>
</Provider>
5.利用connect方法让我们的组件与Store关联
  • 在Btn和Counter组件,分别导入connect方法
arduino 复制代码
import { connect } from "react-redux"
  • 利用connect方法来对我们组件进行加强,并导出
scss 复制代码
export default connect(mapStateToProps,mapDispatchToProps)(Component)
  • connect方法接受两个参数:mapStateToPropsmapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者(在我们的例子中指Counter组件)负责输入逻辑,即将state映射到 UI 组件的参数(props),后者(在我们的例子中指Btn组件)负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
  • 在我们的这个例子中,组件Btn属于发送方,所以要实现connect的第二个参数
  • 在我们的这个例子中,组件Counter属于发送方,所以要实现connect的第一个参数
5.1 Btn组件发送action
javascript 复制代码
import { connect } from "react-redux"

const Btn=(props) =>{
  const handleSend=()=>{
  
    // 发送action
    props.sendAction()
    
  }
  return (
    <button onClick={handleSend}>+(发送方)</button>
  )
} 

// 这个函数要有一个返回值,返回值是一个对象,映射到Btn的props
const mapDispatchToProps= (dispatch)=>{
  return {
    sendAction: ()=>{
    
      // 利用dispatch发送一个action
      dispatch( {type:'add_action'} )
      
    }
  }
}
// Btn,所以要实现connect的第二个参数
export default connect(null,mapDispatchToProps)(Btn)
5.2 Counter组件接收state
javascript 复制代码
import { connect } from "react-redux"

 const Counter=(props)=> {
  return (
    <button>{props.count}(接收方)</button>
  )
}

// 映射state到Counter的props
const mapStateToProps = (state)=>{
  return state
}
export default connect(mapStateToProps)(Counter)

三、Redux-Toolkit

1、redux-toolkit是什么

我们知道,在使用 redux 时,整个流程设计 action, reducer, store, 再到 UI 的重回,不管页面做什么一个小的改变,我们都需要手动地去派发 action,使得 reducer 更新 store 中的数据。redux 现在提供了一个 toolkit 工具包,可以让我们的步骤进行简化。

2、redux-toolkit的使用
2.1 安装redux-toolkit
bash 复制代码
npm install @reduxjs/toolkit react-redux
2.2 redux-toolkit使用步骤
  • 使用 configureStore 创建 Redux store

  • 为 React 应用程序组件提供 Redux store

  • 使用 createSlice 创建一个 Redux "slice" reducer

  • 在 React 组件中使用 Redux Toolkit useSelector/useDispatch 钩子

2.3 redux-toolkit使用示例
2.3.1.创建Store,我们首先创建一个空的 Redux store,并导出它
javascript 复制代码
import { configureStore } from "@reduxjs/toolkit";

export default configureStore({
  reducer:{},
})
2.3.2 创建 store 后,我们可以通过在app.jsx里导入我们刚刚创建的 Redux store,并导入Provider组件进行包裹
javascript 复制代码
import store from './redux-toolkit-demo/store'
import { Provider } from 'react-redux'

<Provider store={store}>
    <App />
</Provider>
2.3.3 创建 Redux State Slice,我这里创建名为 counterSlice 的新文件
javascript 复制代码
import { createSlice } from "@reduxjs/toolkit";

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

export const {increment,decrement} = counterSlice.actions
export default counterSlice.reducer
2.3.4 将我们创建的Slice Reducer 添加到我们的 Store,在这个例子中是counterSlice
javascript 复制代码
import counterReducer from "./counterSlice";

export default configureStore({
  reducer:{
  
    counter: counterReducer, // 添加
    
  },
})
2.3.5 在 Counter 组件中使用 Redux State 和 Actions
javascript 复制代码
import { useSelector,useDispatch } from "react-redux";
import { decrement, increment } from "./counterSlice";

export default function Counter() {

  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();
  
  return(
    <div>
      <div>
        <button
          onClick={() => dispatch(increment())}
        >
          +
        </button>
        <span>{count}</span>
        <button
          onClick={() => dispatch(decrement())}
        >
          -
        </button>
      </div>
    </div>
  )
}

现在,只要我们单击 "+" 和 "- 按钮":

  • 相应的 Redux action 将被 dispatch 到 store
  • counter slice reducer 将看到 action 并更新其 state
  • 该组件将从 store 中看到新的 state 值,并使用新数据重新渲染自身<Counter>
其实看的时候感觉可能还是只有一个懵懂的印象,确实还是需要自己手动去敲一遍才会熟悉,大家多动动手吧~~ 更多详细的可以移步官方文档~~
相关推荐
sen_shan30 分钟前
Vue3+Vite+TypeScript+Element Plus开发-04.静态菜单设计
前端·javascript·typescript·vue3·element·element plus·vue 动态菜单
旧识君1 小时前
移动端1px终极解决方案:Sass混合宏工程化实践
开发语言·前端·javascript·前端框架·less·sass·scss
吃没吃1 小时前
vue2.6-源码学习-Vue 核心入口文件分析
前端
Carlos_sam1 小时前
Openlayers:海量图形渲染之图片渲染
前端·javascript
XH2761 小时前
Android Retrofit用法详解
前端
鸭梨大大大1 小时前
Spring Web MVC入门
前端·spring·mvc
吃没吃2 小时前
vue2.6-源码学习-Vue 初始化流程分析 (src/core/instance/init.js)
前端
XH2762 小时前
Android Room用法详解
前端
木木黄木木2 小时前
css炫酷的3D水波纹文字效果实现详解
前端·css·3d
郁大锤3 小时前
Flask与 FastAPI 对比:哪个更适合你的 Web 开发?
前端·flask·fastapi