React学习(Redux学习)(day4)

Redux

Redux是React最常用的集中状态管理工具,类似于pinia(vues),可以独立于框架运行。

作用:通过集中管理的方式管理应用的状态

使用步骤

1.定义一个reduce函数(根据当前想要做的修改返回一个新的状态)

2.使用createStore方法传入reducer函数生成一个store实例对象

3.使用store实例的subscribe方法 订阅数据的变化(数据一旦变化,可以的到通知)

4.使用store实例的dispatch方法提交action对象触发数据变化(告诉reducer你想怎么改变数据)

5.使用store实例的getState方法获取最新的状态数据跟新到视图中

<button id="decrement">-</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>

Redux管理数据流程梳理

分为三个核心概念,分别是:state、actin、reducer

1.state -- 一个对象 存放着我们管理的数据状态

2.action -- 一个对象 用来描述想要改的数据

3.reducer -- 一个函数 更具action的描述生成一个新的state

在React项目中使用redux,还需要安装两个插件 - Redux Toolkit 和 react-redux

编写子模块内容

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

const counterStore = createSlice({
  name:'counter',
  //初始状态数据
  initialState:{
    count:0
  },
  //修改数据的同步方法
  reducers:{
    inscrement(state){
      state.count++
    },
    decrement(state){
      state.count--
    },
  }
})


//解构处创建action对象的函数 (actionCreater)
const {inscrement,decrement} = counterStore.actions
//获取reducer函数
const counterReducer = counterStore.reducer
//导出创建action对象的函数和reducer函数
export {inscrement,decrement} 
export default counterReducer

编写根store,导入子模块

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

import counterReducer from "./modules/counterStore";

//创建根store组合子模块
const store = configureStore({
  reducer:{
    counter: counterReducer
  }
})

export default store

最后为React注入store

内置Provider组件通过store参数把创建好的store实例注入到应用中,链接正式建立。

//导包
import store from './Store';
import { Provider } from 'react-redux';    

//注入
<Provider store ={store}>
      <App />
</Provider>

React组件使用store中的数据

使用到一个钩子函数 - useSelector ,其作用是把store中的数据映射到组件中

import { useSelector } from "react-redux";

function App() {
  const {count} = useSelector(state =>state.counter)
  return (
    <div className="App">
      {count}
    </div>
  );
}

export default App;

React组件修改store中的数据

React组件修改store中的数据需要借助另外一个hook函数 - useDispatch,它的作用是生成提交action对象的dispatch函数

import {useDispatch, useSelector } from "react-redux";

//导入actionCreater
import { inscrement,decrement } from "./Store/modules/counterStore";

function App() {
  const { count } = useSelector(state =>state.counter)
  const dispatch = useDispatch()
  return (
    <div className="App">
      <button onClick={()=>dispatch(decrement())}>-</button>
      { count }
      <button onClick={()=>dispatch(inscrement())}>+</button>
    </div>
  );
}

export default App;

提交action传参实现需求

在reducers的同步修改方法中添加action对象参数,在调用actionCreater的时候传递参数,参数会被传递到action对象display属性上

//!!!!!store子模块!!!!!
import { createSlice } from "@reduxjs/toolkit";

const counterStore = createSlice({
  name:'counter',
  //初始状态数据
  initialState:{
    count:0
  },
  //修改数据的同步方法
  reducers:{
    addToNum(state,action){
      state.count = action.payload
    }
  }
})


//解构处创建action对象的函数 (actionCreater)
const {addToNum} = counterStore.actions
//获取reducer函数
const counterReducer = counterStore.reducer
//导出创建action对象的函数和reducer函数
export {addToNum} 
export default counterReducer


//!!!!!React组件内使用!!!!!
import {useDispatch, useSelector } from "react-redux";

//导入actionCreater
import {addToNum} from "./Store/modules/counterStore";

function App() {
  const { count } = useSelector(state =>state.counter)
  const dispatch = useDispatch()
  return (
    <div className="App">
      { count }
      <button onClick={()=>dispatch(addToNum(10))}>add To 10</button>
      <button onClick={()=>dispatch(addToNum(1314))}>add To 1314</button>
      <button onClick={()=>dispatch(addToNum(0))}>reset</button>
    </div>
  );
}

export default App;

Redux与React异步状态操作

样板步骤:

1.创建store的写法不变,配置好同步修改状态的方法

2.单独封装一个函数,在函数内部return一个新函数,在新函数内:

   封装异步请求获取数据

   调用同步actionCreate传入异步数据生成一个action对象,并使用dispatch提交

3.组件内dispatch的写法保持不变

store子模块

import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const channelStore = createSlice({
  name:'channel',
  initialState:{
    channelList:[]
  },
  reducers:{
    setChannels(state,action){
      state.channelList = action.payload
    }
  }
})

//异步请求部分
const {setChannels} = channelStore.actions

const fetchChannlList =()=>{
  const url = 'your api url'
  return async(dispatch)=>{
    const res = await axios.get(url)
    dispatch(setChannels(res.data.channels))
  }
}

export {fetchChannlList} 

const reducer = channelStore.reducer
export default reducer

根store引用

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

import channelReducer from "./modules/channelStore"

//创建根store组合子模块
const store = configureStore({
  reducer:{
    channel: channelReducer
  }
})

export default store

React组件内使用

import {useDispatch, useSelector } from "react-redux";

//导入actionCreater
import { useEffect } from "react";
import { fetchChannlList } from "./Store/modules/channelStore";

function App() {

  const {channelList} = useSelector(state=>state.channel)
  const dispatch = useDispatch()
  //使用useEffect触发异步请求执行
  useEffect(()=>{
    dispatch(fetchChannlList())
  },[dispatch])
  
  return (
    <div className="App">
      <div>
        <ul>
          {channelList.map(item=><li key={item.id}>{item.name}</li>)}
        </ul>
      </div>
    </div>
  );
}

export default App;

Redux调式

使用扩展插件-Redux Devtools

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值