react-day3

90 阅读3分钟

Redux

Redux是react最常用的集中状态管理工具,类似于vue的vuex或者pinia,可以独立于框架运行。

快速使用 使用步骤:

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

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

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

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

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

// 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实例的subscride订阅数据变化
    // 回调函数可以在每次state变化时候执行
    store.subscride(()=>{
    //store.getState()获取最新状态
      console.log('state变化了',store.getState());
    })

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

Redux管理数据流程梳理

Redux把整个数据修改分成了三个核心概念 ,分别是:stateactionreducer

state:一个对象,存放着我们管理的数据状态。

action:一个对象,用来描述你想怎么修改数据

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

Redux在react中的使用

在react中使用redux需要安装两个插件 Redux Toolkitreact—redux

1.Redux Toolkit:官方推荐编写Redux逻辑的方式,是一套工具的集合,简化书写方式

2.react—redux:用来连接react和react组件的中间件

安装命令:npm i @reduxjs/toolkit react-redux

使用React Toolkit 创建counterStore

文件目录结构

|-store

--modules 模块文件夹

----channelStore.js 子模块一

----counterStore.js 子模块二

--index.js 入口文件

index.js

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

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

export default store

counterStore.js

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

export const counterSlice = createSlice({
    name:'counter',
    // 数据初始状态
    initialState:{
        value:0
    },
    // 修改数据的同步方法
    reducers:{
        increment:(state)=>{
            state.value++;
        },
        decrement:(state)=>{
            state.value--;
        }
    }
})

// 解构出action对象的函数并且导出
export const {increment,decrement} = counterSlice.actions;
// 导出reducer 
export default counterSlice.reducer;

为react 注入store

react-redux负责把Redux和react链接起来,内置的 Provider 组件通过store参数把创建好的store实例注入的到应用中建立链接。

import store from "./store/index.js"
import { Provider } from "react-redux"

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
      <App />
    </Provider>
);

在react组件中使用store数据

使用 useSelector 函数,此函数作用是将store中的数据映射到组件中

  const {value} = useSelector((store)=>{
    return store.counter
  })

  return (
    <div className="App">
      {value}
    </div>
  );

在react组件中修改store数据

使用 useDispatch 函数,此函数作用是生成提交action对象的dispatch函数

  const {value} = useSelector((store)=>{
    return store.counter
  })

  const dispatch = useDispatch()
  // increment(),decrement()生成action对象
  return (
    <div className="App">
      <button onClick={()=>{dispatch(increment())}}>+</button>
      <div>{value}</div>
      <button onClick={()=>{dispatch(decrement())}}>-</button>
    </div>
  );

提交action传参

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

传参

      <button onClick={()=>{dispatch(addnum(10))}}>+10</button>

接收

export const counterStore =  createSlice({
    name:'counter',
    initialState:{
        num:0
    },
    reducers:{
        addnum(state,actions){
            // 接收参数,在payload中
            state.num = actions.payload
        },
    }
})

使用redux与react的异步操作

步骤一 创建store的写法保持不变,配置好同步修改的方法

const channel = createSlice({
    name:'channel',
    initialState:{
        list:[]
    },
    reducers:{
        setList(state,action){
            state.list = action.payload;
        }
    }
})

步骤二(关键) 单独封装一个函数,在函数中return出一个新函数,在新函数中封装异步请求获取数据, 在调用同步actionCreater传入异步数据生成一个action对象,并使用dispatch提交

const { setList } = channel.actions;
export const fatchChannelList = ()=>{
    return async (dispatch)=>{
        const res = await axios.get('http://geek.itheima.net/v1_0/channels');
        dispatch(setList(res.data.data.channels))
    }
}

步骤三 在组件中dispatch写法保持不变

 const dispatch = useDispatch()

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