本文介绍: 集中状态管理工具,不需要react即可使用,每个store的数据都是独立于组件之外的vue链接vuex/pinia

一、Redux

集中状态管理工具,不需要react即可使用,每个store的数据都是独立于组件之外的

vue链接vuex/pinia

基本使用

Redux将数据修改流程分成三个概念stateaction和reducer

state – 一个对象 存放我们管理的数据状态

action – 一个对象 描述你如何修改数据

reducer – 一个函数 根据action描述生成新的state

<button id="decrement"&gt;-</button>
<span id="count">0</span>
<button id="increment">+</button>

<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>

<script>
  // 1. 定义reducer函数 
  // 作用: 根据不同的action对象返回不同的新的state
  // state: 管理的数据初始状态
  // action: 对象 type 标记当前想要做什么样的修改
  function reducer (state = { count: 0 }, action) {
    // 数据不可变:基于原始状态生成一个新的状态 所以要返回对象
    if (action.type === 'INCREMENT') {
      return { count: state.count + 1 }
    }
    if (action.type === 'DECREMENT') {
      return { count: state.count - 1 }
    }
    return state
  }

  // 2. 使用reducer函数生成store实例
  const store = Redux.createStore(reducer)

  // 3. 通过store实例的subscribe订阅数据变化
  // 回调函数可以在每次state发生变化的时候自动执行
  store.subscribe(() => {
    console.log('state变化了', store.getState())
    document.getElementById('count').innerText = store.getState().count
  })

  // 4. 通过store实例的dispatch函数提交action更改状态 
  const inBtn = document.getElementById('increment')
  inBtn.addEventListener('click', () => {
    // 增
    store.dispatch({
      type: 'INCREMENT'
    })
  })

  const dBtn = document.getElementById('decrement')
  dBtn.addEventListener('click', () => {
    // 减
    store.dispatch({
      type: 'DECREMENT'
    })
  })

  // 5. 通过store实例的getState方法获取最新状态更新视图中

</script>

react中使用redux

相关工具

Redux Toolkit 简化redux书写逻辑

react-redux 链接Redux和React的中间件

npm i @reduxjs/toolkit react-redux

 安装成功

目录创建

创建src/store,modules存放子模块

counterStore.js

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"

const counterStore = createSlice({
    name:'counter',
    // 初始状态
    initialState:{
        count:0
    },
    // 更新状态的方法
    reducers:{
        inscrement(state){
            state.count++
        },
        descrement(state){
            state.count --
        }
    }
})

const {inscrement, descrement} = counterStore.actions
const reducer = counterStore.reducer

export{
    inscrement,
    descrement
}

export default reducer

store/index.js

集成store/modules中所有子模块

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore"

// 将子模块中的所有store合成一个根store方便访问
const store = configureStore({
    reducer:{
        counter:counterReducer,
    }
})

export default store

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from "./store"
import { Provider } from 'react-redux';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  // 通过react-redux提供的Provider 给组件注入store 使得redux定义的store能够被react组件使用
  <Provider store={store}>
    <App />
  </Provider>
);

App.js

useDispatch() 通过这个来派发reducer修改状态

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement} from "./store/modules/counterStore"
function App() {
  const { count } = useSelector(state => state.counter)
  const dispatch = useDispatch()
  return (
    <div className="App">
      <button onClick={() => dispatch(inscrement())}>+</button>
      {count}
      <button onClick={() => dispatch(descrement())}>-</button>
    </div>
  );
}

export default App;

然后就完成了:

进阶版-提交action时传参

counterStore.js

增加了一个addToNum函数

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"

const counterStore = createSlice({
    name:'counter',
    // 初始状态
    initialState:{
        count:0
    },
    // 更新状态的方法
    reducers:{
        inscrement(state){
            state.count++
        },
        descrement(state){
            state.count --
        },
        addToNum(state, action){
            // dispatch调用方法时传入的参数就存放在action.payload
            state.count += action.payload
        }
    }
})

const {inscrement, descrement, addToNum} = counterStore.actions
const reducer = counterStore.reducer

export{
    inscrement,
    descrement,
    addToNum
}

export default reducer

 App.js

增加了两个值,传入不同参数

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
function App() {
  const { count } = useSelector(state => state.counter)
  const dispatch = useDispatch()
  return (
    <div className="App">
      <button onClick={() => dispatch(inscrement())}>+</button>
      {count}
      <button onClick={() => dispatch(descrement())}>-</button>
      <button onClick={() => dispatch(addToNum(10))}>+ 10</button>
      <button onClick={() => dispatch(addToNum(-10))}>- 10</button>
    </div>
  );
}

export default App;

再进阶版-异步状态操作

channelStore.js

import {createSlice} from '@reduxjs/toolkit'
import axios from 'axios'

const channelStore = createSlice({
    name:'channel',
    initialState:{
        channelList:[]
    },
    reducers:{
        getChannels(state, action){
            state.channelList = action.payload
        }
    }
})

const {getChannels} = channelStore.actions


//单独写一个异步action的函数 异步操作处理完毕后再调用同步action修改状态
const getChannelList = () => {
    return async(dispatch) => {
        const res = await axios.get('http://geek.itheima.net/v1_0/channels')
        dispatch(getChannels(res.data.data.channels))
    }
}

export {getChannelList}

const reducer = channelStore.reducer
export default reducer

 App.js

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
import {getChannelList} from "./store/modules/channelStore"
import {useEffect} from 'react'
function App() {
  const { count } = useSelector(state => state.counter)
  const { channelList } = useSelector(state => state.channel)
  const dispatch = useDispatch()

  useEffect(()=> {
    dispatch(getChannelList())
  }, [dispatch])
  
  return (
    <div className="App">
      <button onClick={() => dispatch(inscrement())}>+</button>
      {count}
      <button onClick={() => dispatch(descrement())}>-</button>
      <button onClick={() => dispatch(addToNum(10))}>+ 10</button>
      <button onClick={() => dispatch(addToNum(-10))}>- 10</button>
      <ul>
        {channelList.map(item => <li key={item.id}>{item.name}</li>)}
      </ul>
    </div>
  );
}

export default App;

调试工具redux devtools

直接在chorme商店里下载

 

原文地址:https://blog.csdn.net/Michelle209/article/details/134573638

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_1929.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注