关于redux在react中的应用总结

  • Post author:
  • Post category:其他




redux

javascript提供的一个可预测性的状态容器(我们给一个固定的输入 那麽必定可以得到结果)

集中的的管理react当中多个组件的状态

redux是一个专门的状态管理库 (是一个插件 在vue也可以使用 但是在react比较多)

cnpm istall redux --save

store 状态仓库

reducer 处理业务逻辑

需求场景

某个组件的状态需要共享的时候

一个组件需要改变另一个组件状态的时候

组件的状态需要在任何地方可以拿到



三大原则

1.单一数据源 整个react中的状态 都会被统一的管理到store里面

2.state是只读的 不能够直接改变state 二是通过触发redux中的特定方法修改state

3.使用纯函数来执行修改操作:action来改变redux的state

初始化阶段通过store.getState() 获取

redux 可以理解为:界面上触发了需要改变数据的事件会在callback里面创建action 并且用dispatch提交action 这个action会被提交到store里的reducer(可以是一个模块,也可能与创建store集成在一起,也可能是用hooks创建的reducer) 接收到action提交后 会首先比较type类型 再利用action里的其他属性 在对应代码块里进行逻辑操作 实现状态的变化

1.辅助工具 :store一被提交的action修改 可以使用store.subscribe(“回调”)更新到新的状态 实现’刷新‘

const  [val,setVal] = useState(store.getState())
const getNewState=()=>{
    setVal(()=>{return store.getState()})    //setVal 的更新可能是异步的 所以要传一个callback
}
store.subscribe(getNewState)

2.如何在全局调用store的具体数据

react-redux

Provider 提供器 将store的状态给到 组件 【一般是在入口函数 或者父组件使用 包裹住需要拿到状态的组件】

connect 在上面被包裹的组件 导出的时候再来一次包裹 connect(mapStateToprops,mapDispatchToprops)(App) connect的两个方法会将状态 和修改状态的方法 dispatch 通过props传给 包裹住的组件【这两个方法的使用场景是已经有store的时候 将state给到需要组件 】

入口函数:引入Provider 包裹住引来的跟组件

跟组件:再导出时 在外套上connect(mapStateToprops,mapDispatchToprops)(App) 两个形参介绍如下

const mapStateToprops=(state)=>{
    return state
}
const mapDispatchToprops=(dispatch)=>{
    return(
        add(e){
            const action ={
                type="ADD_ITEM",
                value=e.target.val
            }
            dispatch(action)
        },
    )
}

3.要调用多个接口 且需要存在store中时 按需拿到 少调接口 所以要分别对应不同的reducer, 合并reducer

const reducer = combineReducer({
    user:data1,
    product:data2
})
const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)

4.useContext 上下文 个人理解:

与eventBus相似 在总线中

A.vue 与 B.vue 需要引入总线传参import EventBus from “event Bus.js ”

A.vue

method:{
    toFriend(e){
        EventBus.$emit("coming",e.target)
    }
}

B.vue

created(){
    EventBus.$on("coming",target=>{
        console.log(target)
    })
}

vue路由懒加载

1.正常情况下

import Hello from './components/Hello'

2.使用ES的懒加载

const Hello = ()=>import('./components/Hello')
在路由规则里 component:()=>import ('./components/Hello')

3.require

component : resolve =>{require('[./components/Hello]',resolve)}

useContext的模拟使用 用上面的 文件名模拟

eventBus.jsx:

export const Acontext = createContext() //创建一个上下文 并暴露
export const Bcontext = createContext()
const [count,setCount] = useState('0')
const [name,setName] = useState('kenny')
return (
  <div>
    <Acontext.Provider value={count}>
        <A />
    </Acontext.Provider>
    <Bcontext.Provider value={name}>
        <b />
    </Bcontext.Provider>
  </div>
) 
A.jsx: 
const count = useContext(Acontext)
{count}
B.jsx:
const name= useContext(Bcontext)
{name}

usereducer

接受两个参数,一个是reducer,一个是状态的默认值, reducer接受两个参数 一是state 一是action(这里的state就是状态的默认值)

然后返回一个状态count和dispatch dispatch可以发布事件 更新state

import React,{useReducer} from "react"
function Text(){
    const [count,dispatch] = useReducer((state,action)=>{
        switch(action.type){
            case "add"
                return state + +action.val
            case "del"
                return state -  action.val
        }
    },10)
    return(
        <div>
            <p>{count}</p>
            <button onClick={()=>{return dispatch({type:"add",val:2})}}>2</button>
            <button onClick={()=>{return dispatch({type:"del",val:3})}}>3</button>
        </div>
    )
}

createContext 创建上下文 useReducer与useContext 相结合 可以实现 redux的作用

这里需要专门建立模块的利用useContext的上下文暴露 (contextName.Provider)将useReducer的状态和diapatch暴露出去

不过需要注意 这里导出的该模块 是要将可能用到state状态的某些模块包裹起来 再在相应的模块里面用对象解构引用上下文

redux-thunk 可以dispatch一个函数 中间件

redux-saga 用于管理redux应用异步操作的中间件 (又称异步action)

saga 通过创建sagas 将所有的异步操作逻辑收录在一起 可以代替thunk中间件

sagas通过Generator来创建 可以用同步的方式写异步代码

thunk是在action被创建时调用 saga则是在应用启动时调用 监听发起的action 基于这个action来做什么



useSlector

在函数组件中结合reducer使用方便快捷(推荐使用)与useDispatch搭配使用

const {keyword} = useSelector(state => state.search);



版权声明:本文为weixin_45942049原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。