• react中redux怎么使用


    一、redux是什么?

    redux 就是react 全局状态管理,作用是存放全局数据

     

    二、核心

    1. state:存放数据

    2. reducer:修改仓库数据

    • 是一个函数,参数一:仓库中的数据,参数2:行为 actions

    • 返回值就是 最新的仓库数据

    • 就是在reduce中定义的方法,修改数据,相当于mutations

    • 只能是同步方法

    1. actions:派发行为触发reducer; 语法:sotre.dispatch({type:'add'})

    2. 语法:

    复制代码
    function  reducer( state={age:10,name:'lisa' },actions){
            switch(action.type){
                case "add":
                    return {...state,  age:state.age+1 };
                case "reduce":
                    return { age:state.age-1 }
                default:
                    return state
            }
        }
    复制代码

     

    三、使用redux

    1、安装redux
    # NPM
    npm install redux
    
    # Yarn
    yarn add redux
    2、在src目录下创建store文件夹,index.js文件

    在项目中使用到哪些api

    1. createStore

      • 作用:创建仓库

      • 语法:let store=createStore(reducer,中间件);

      • 输出store:

        • @@observable: ƒ observable() 观察仓库中的数据、

        • dispatch: ƒ dispatch(action) 触发reducer、

        • getState: ƒ getState()获取到仓库中的数据、

        • replaceReducer: ƒ replaceReducer(nextReducer) 替换reducer、

        • subscribe: ƒ subscribe(listener) 订阅

    复制代码
    //创建仓库
    
    import {createStore} from 'redux'
    
    
    // createStore=>创建仓库
    //语法
     //let store = createStore(reducer,中间件)
    
    
     // reducer =>  自己定义
    
     // 1他是一个函数
     // 2参数1 仓库中的数据   参数2 行为 actions
     // 3这个reduer 返回值 就是最新的仓库中的数据 
     // 4redcuer =》就是在reducer中定义方法修改数据 =》vuex mutations
    
    
     function reducer(state={age:10},actions){
          switch(actions.type){
            case "add":
                console.log('add',state);
                return {age:state.age+1};
             default :
             return state
          }
     }
    
     let store = createStore(reducer)
    
    
    /**
     * 
     * @@observable: ƒ observable()  观察仓库中的数据
    dispatch: ƒ dispatch(action)  =》触发reducer
    getState: ƒ getState()  =>获取到仓库中的数据
    replaceReducer: ƒ replaceReducer(nextReducer)  替换reducer
    subscribe: ƒ subscribe(listener)  订阅
     * 
     * 
     * 
     * **/
    
       export default store
    复制代码
    3、在App.js根组件中使用仓库
    1. 在组件中使用仓库

      1. 引入仓库 import store from './store/index'

    2. 获取仓库中的数据:store.getState().meReducer.age; (meReducer.age指的是meReducer中的age属性)

    3. 触发reducer:store.dispatch({type:"add"})

    复制代码
    import logo from './logo.svg';
    import './App.css';
    // 在组件中引入仓库
    import store from './store/index'
    import {useState} from 'react'
    
    function App() {
     // 1获取到仓库中的数据
      // console.log(store.getState());
      // let age = store.getState().age
      let [age,setAge] = useState(store.getState().age)
    
      const changeAge = ()=>{
         //触发 reducer
         store.dispatch({type:'add'})
        //  问题=》仓库中的数据更新了=》但是视图没有更新 =》组件没有更新
        // 1 讲这个数据=》动态数据
        // setAge(仓库中的最新数据) =>和仓库进行关联
        setAge(store.getState().age)
      }
      return (
        

    我的年龄{age}

    ); } export default App;
    复制代码

     

    四、combineReducers 合并reducer

    combineReducers:

    1. 作用:合并reducer

    2. 语法:let reducers = combineReducers({属性:各自的reducer, 属性:各自的reducer})

    使用webpack中的api:require.context 自动获取到文件中的暴露的内容

    1. 作用:通过该函数可以获取一个上下文,从而实现工程自动化(遍历文件夹的文件,从中获取指定文件,自动导入模块)。在前端工程中,如果一个文件夹中的模块需要频繁引用时可以使用该中方式一次性引入

    2. 语法:let webf = require.context('文件路径',布尔值,正则)

    返回值: 1 webf.keys() 返回一个数组,由匹配成功的文件所组成的数组 2 webf(路径).default 获取到路径中导出的模块

    手动合并reducer

    复制代码
    //  合拼reducer
    
    import {combineReducers} from 'redux'
    
    // combineReducers
    import CartReducer from './CartReducer'
    import meReducer from './meReducer'
    //作用:合拼reducer
    //语法: let reducers = combineReducers({属性:各自的reducer,属性:各自的reducer})
    
    
    let reducers = combineReducers({
        CartReducer,
        meReducer
    })
    
    export default reducers
    复制代码

    工程化处理reducer 合拼

    复制代码
    /* 
        combineReducer
            作用: 合并 reducer 数据实现模块化
            语法:let reducers=combineReducers({属性:各自的reducer, 属性:各自的reducer})
    */
    
    // 工程化处理Reducer 合拼
    
    import { combineReducers } from "redux";
    
    // combineReducers
    import CartReducer from "./CartReducer";
    import MeReducer from "./MeReducer";
    // 在这里引入各自的reducer
    // 处理方法 =》 自动引入reducer 自动合拼reducer
    
    // 1 在reducers文件夹下创建一个 reducer 文件 =》 再给我 合拼成reducer
    
    // 1 webpack =》 require.context =》自动获取到文件中的暴露内容
    
    // 语法:require.context('文件路径',布尔值,正则)
    // requeire.context('文件路径',布尔值,正则)  => 返回值  (是webpack)实例方式
    
    // 两个方法 1. webf.keys()=>['文件路径',布尔值,正则]
    // 2.获取到它的内容 webf(路径).default
    
    let webf = require.context("./", true, /\.js/);
    let webfList = webf.keys();
    // console.log(webfList);
    // 删除自身 index.js
    let index=webfList.findIndex((item,index)=>{
        return item=='./index.js'
    })
    webfList.splice(index,1)
    // console.log(webfList);
    
    // 将webfList合并成一个对象
    let objs={};
    webfList.forEach((item,index)=>{// 文件路径     ./ CartReducer .js
            // console.log(webf(item).default);
            // 处理属性 = item
            let items=item.replace('./','').replace('.js','')
            // console.log(items)
            objs[items]=webf(item).default
    })
    // console.log(objs)
    
    // 作用:合并reducer
    // 语法:let reducers=combineReducers({属性:各自的reducer,属性:各自的reducer})
    
    let reducers = combineReducers(objs);
    
    export default reducers;
    复制代码

     

    五、bindActionCreators 自动触发reducer

    1. 作用:实现自动派发,实现行为 reducer 处理方法一一对应

    2. 语法:let 对象 = bindActionCreators({属性:属性值是一个方法},store.dispatch),属性值是一个方法 => 就是你的reducer中的方法

    3. 实现步骤:

    复制代码
    /* 
        五:bindActionCreators
    
        bindActionCreators => 自动触发reducer => 你想要触发
    
        语法:let 对象 =bindActionCreators({属性:属性值是一个方法},dispatch)  属性值是一个方法=》 就是你的reducers中的方法
    
    
        使用: 
            1 实现reducer 和他的行为一一对应
            2 使用 bindActionCreators 来实现
                2.1 语法 bindActionsCreators({就是你的reducer 和 使用的行为对应},dispatch)
    
             全部触发我的模板中的reducer 行为
                 1 我的模块reducer 有多少个行为
                 2 我的模块中add
            
        */
    
    import { bindActionCreators } from "redux";
    import store from "../index";
    
    // bindActionCreators => 自动触发reducer => 你想要触发
    // 语法 let对象 =bindActionCreators({属性:属性值是一个方法},dispatch),属性值是一个方法 =》就是你的reducer中的方法
    
    // 创建方法
    let meAdd = () => {
      return {
        // 行为 =》 actions
        type: "add",
      };
    };
    
    let meSub = () => {
      return {
        type: "sub",
      };
    };
    
    let meActions = bindActionCreators({ meAdd, meSub }, store.dispatch);
    
    export default meActions;
    复制代码
    1. 引入这个自动派发的方法 :直接使用

    复制代码
    import logo from './logo.svg';
    import './App.css';
    //来到组件
    import store from './store/index'
    import {useState} from 'react'
    
    //使用 自动派发
    import meActions from './store/actions/meActions'
    
    function App() {
     // 1获取到仓库中的数据
      console.log(store.getState());
      // let age = store.getState().meReducer.age
      let [age,setAge] = useState(store.getState().meReducer.age)
    
    // 3引入我们这个自动派发的方法 =》直接使用
      const changeAge = ()=>{
          console.log( meActions);
        //  store.dispatch({type:'add'}) //触发reducer
        meActions.meAdd()
     
        setAge(store.getState().meReducer.age)
      }
    
      return (
        

    我的年龄{age}

    ); } export default App;
    复制代码

     

    六、React Redux

    1、为什么应该使用React-Redux?

    因为React是一个独立的库,可以与React、Vue、Angular一直使用,但是它们是相互独立的;

    如果想要同时使用 Redux 和 React,应该使用 React-Redux 来绑定这两个库

    react-redux是连接react和redux 的桥梁,让react中使用redux时低耦合,方便快捷 react-redux 提供了两个 api

    1. 作用:提供全局组件和hooks,在父级组件提供仓库组件,在自己组件中获取到仓库的数据

    2. Provider 为后代组件提供 store

    3. connect 为组件提供数据和变更⽅法

    核心:为我们react项目提供的一个组件,两个hooks

    组件:Provider 1 作用:在父级组件中提供数据 ,其他的子集组件就可以获取到;

    2 在父组件中提供了数据 store;

    hooks:

    useSelector 1 作用:在组件中获取仓库中的数据,再通过useState修改数据方法,让数据更新

    2 语法:useSelector(state => { return 返回值}) // 返回 在仓库中获取的数据

    useDispatch 1 作用:可以获取到更新组件的dispatch,先触发reducer,

    2 语法:let dispatch=useDispatch(); dispatch({type:'add'});

     

    2、在项目中使用React-redux

    1. 安装react-redux

    npm install react-redux

      2.在入口文件中使用Provider提供仓库store

    复制代码
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import { Provider } from 'react-redux';
    import store from './store';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      
        {/* 在父组件中提供数据 */}
        
      
    );
    复制代码

    3.useSelector使用

    4.useDispatch使用

    复制代码
    /* 
       react-redux 作用
          提供 1 组件 =》 在子级组件提供仓库组件,在自己组件中获取到仓库数据
          2 hooks  
    
          useSelector => 得到仓库中的数据
          // 语法
          useDispatch 作用:可以获取到更新组件的dispatch;触发 reducer  =》 语法 useDispatch() => dispatch()
    */
    
    // 使用
    // 在自己组件中获取到仓库中的数据 =》 使用它提供的两个hooks
    import {useSelector,useDispatch} from 'react-redux' 
    // useSelector(state=>{返回值}) =》返回值  得到仓库中的数据
    // useDispatch 触发redcuer =》 语法 useDispatch()=> 的返回值就是 dispatch()
          // 作用:获取到可以更新组件的dispatch
    
    function App(){
      let age=useSelector(state=>{  // state是来自父组件的store数据
        return state.MeReducer.age
      })
    
      let dispatch=useDispatch() // 1 先触发reducer,获取到仓库中的数据,再通过useState修改数据方法,让数据更新
      console.log(age,'组件重新创建');
    
      return(
          

    我的年龄{age}

    ) } export default App /* 总结:react-redux 作用:让仓库和react项目进行关联 它为react项目提供了一个组件(Provider),两个hooks(useSelector、useDispatch) Provider: 在父级组件中提供数据,其他的自己组件就可以获取到 useSelector:在组件获取到仓库中的数据 useDispatch:先触发reducer,获取到仓库中的数据,再通过useState修改数据,让数据更新 */
    复制代码

     

    七、异步actions

    1、为什么需要处理异步?

    因为reducer 只能处理同步问题,但是我们在工作中,可能需要在仓库中发生请求,获取到异步的数据

    2、异步actions作用?

    1)在仓库中获取异步收据 2)触发reducer 修改仓库中的数据

    3、实现异步actions?
    1. 在store文件夹下创建一个 actions 文件夹,实现 异步actions 和各自的reducer 一一对应

    复制代码
    //我的模块中 异步处理
    import axios from 'axios'
    import store from '../index'
     // 定义异步处理方法
    
     //根据actions作用来进行定义 =》1 获取到异步数据   2 触发reducer
    
     //定义异步处理方法
     // 1 是一个方法
     // 2 获取到异步数据
     // 3 触发reducer   => store
      export  function   getAgeSub(){
           
         //1获取到异步数据
         function getData(){
            return  axios.get('').then(res=>{ //后端给的数据
                  let a = 100
                  return a
              })
         }
    
         // 2触发reducer
         return  async()=>{
              // 1获取到异步数据
            let data =   await getData()
            console.log(data);
              // 2 触发reducer =>将异步数据传递给 reducer
              console.log('触发reducer');
              store.dispatch({type:'add',data })
         }
     }
    
     // getAgeSub()
    
     //总结 定义actions 
     //1 获取到异步数据
     //2 触发reducer
     //3 知道执行的获取到异步数据,再 执行reducer
    
     //定义异步actions => 函数劫持
    //高阶函数=》  1 这个函数的参数是一个函数  或者 这个函数的返回值是一个函数
     // 函数劫持 =》我在处理某个逻辑之前,要做一些操作,我们把这个方法叫做函数劫持
    复制代码
    4 、在组件中使用 dispatch 触发异步actions

    会报错 => 需要使用 1 中间件 2 redux-thunk

    redux-thunk =》 作用1:处理异步action =》 给 异步action触发方法,第一个参数 就是dispatch

    5、配置中间件 =》redux-thunk
    1. 在store/index.js 文件中进行配置

    2. 安装redex-thunk

    npm install redux-thunk
    复制代码
    // 引入中间件
    import {createStore,applyMiddleware} from 'redux'
    import reducers from './reducers'
    // 引入'redux-thunk'
    import ReduxThunk from 'redux-thunk'
    
    
    
    let store = createStore(reducers,applyMiddleware(ReduxThunk))
      //applyMiddleware(ReduxThunk) =>1处理组件中 dispatch()这个方法内容可以写 方法 
      // 2 异步actions 返回的处理方法 的第一次参数就是dispatch
    
    
    export default store
    复制代码
    6、在其他组件中触发异步actions

    创建 异步actions 返回的处理方法 的第一次参数就是dispatch

    复制代码
    export  function   getAgeReduce(){
           
        //1获取到异步数据
        function getData(){
           return  axios.get('').then(res=>{ //后端给的数据
                 let a = 100
                 return a
             })
        }
    
        // 2触发reducer
        return  async(dispatch)=>{ //第一个参数 就是  dispatch
             // 1获取到异步数据
           let data =   await getData()
           console.log(data);
             // 2 触发reducer =>将异步数据传递给 reducer
             console.log('触发reducer');
          
            dispatch({type:'reduce',data })
        }
    }
    复制代码

     

    总结

     

  • 相关阅读:
    VMware虚拟机三种网络模式
    C++设计模式之装饰者模式(结构型模式)
    呼叫中心自建好还是云外呼好用?
    8-13外部排序-败者树
    windows下域名解析及修改hosts文件不起作用的问题解决
    Vuex数据持久化存储
    【Maven教程】(八):使用 Nexus 创建私服 ~
    Kibana安装、配置
    TIDB-PD-RECOVER的恢复方式
    JavaWeb:JavaWeb技术架构演进
  • 原文地址:https://www.cnblogs.com/chccee/p/17138406.html