redux使用详解

安装

npm install redux react-redux -S

  1. redux 这个包是在 action.js store.js reducer.js 中使用的;
  2. react-redux 这个包是在 react 的组件中使用的;

Redux 概念

  1. store 对象:这个 store 类似于 vuex 中的全局 new Vuex 对象,负责连接 action 和 reducer,是一个核心;
  2. action 对象:类似于 vuex 中的 mutation 和 action 的集合,它既支持同步操作数据,也支持异步操作数据,主要作用就是 通过 dispatch 提交 action,触发 修改 state 数据的行为;
  3. reducer 对象:类似于 vuex 中 state 属性,负责初始化 state 数据以及更新 state 数据;

Redux 用法

  1. 在 ./src/store.js 文件中创建 redux 的 store 对象,用于管理 action 和 reducer

    import { createStore } from "redux";
    
    // 导入 reducer
    import reducer from "./reducer";
    
    // 在创建 store 对象的时候,要进行 state 的初始化操作,因此,createStore() 函数中必须要绑定 reducer,也就是让 reducer 和 store 产生关联,这样如果后期有 action 产生的时候,store 就会将这个 action 对象,转发给 reducer。
    let store = createStore(reducer);
    
    // 暴露这个store对象
    export default store;
    
  2. 由于 store 对象初始化的时候,要同时进行 state 的初始化,因此,在 ./src/reducer.js 文件中定义出来想要保存到 redux 中的 state。

     import { combineReducers } from "redux";
    
     // name是一个 reducer 对象,age 也是一个 reducer 对象
     function name(state = "", action) {
       // 暂时用不到 修改state
       return state;
     }
    
     function age(state = 0, action) {
       return state;
     }
    
     // combineReducers() 可以将多个 reducer 对象合并成一个 reducer 对象,因为 createStore() 中只能设置一个 reducer
     export default combineReducers({
       name,
       age,
     });
    
  3. 在 根组件 index.js 文件中,绑定 store,让组件和 redux 进行绑定。、

    // 让 redux 中的 store 对象 和 react 中的组件产生关联;
    import { Provider } from "react-redux";
    // 导入 创建好的 store 对象
    import store from "./store/store";
    
    ReactDOM.render(
      <Provider store={store}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </Provider>,
      document.getElementById("root")
    );
    
  4. 可以在任何一个组件中,去使用 redux 中的数据了。

     import { connect } from "react-redux";
     // connect()(Home) 该方法并不会修改原有组件 Home 的内容,仅仅是在 Home 组件的基础上包装上了 Redux 的内容
     // connect(参数1,参数2):这两个参数都是函数,并且connect在执行函数回调的时候,会传递两个参数进来,一个参数就是state,这个state内,存储的就是 reducer.js 中声明的 数据(name,age)。
     export default connect(
       (state) => {
         return {
           myName: state.name, // 相当于在当前 Home 组件中映射一个属性叫 myName,当前组件就可以使用 myName
           myAge: state.age, // 相当于在当前 Home 组件中映射一个属性叫 myAge,当前组件就可以使用 myAge
         };
       },
       (dispatch) => {
         return {};
       }
     )(Home);
    

    注意:组件中映射的 myName 和 myAge 属性,都被放在了 当前组件的 props 中。

  5. 如何通过 派发 action ,修改 state 的数据

    action.js 文件中定义 各种 action

     // 定义 修改name 的action
     function setName(value) {
       return {
         type: "SET_NAME",
         value,
       };
     }
    
     // 定义 修改age 的action
     function setAge() {
       return {
         type: "SET_AGE",
       };
     }
    
     export { setName, setAge };
    

    在组件中映射 action 到当前组件

     (dispatch) => {
       return {
         // 目的:在当前组件中映射一个方法,方法名称是 customChangeName。
         customChangeName(name) {
           dispatch(setName(name)); // 派发action,交给 store,store 对象会将 这个 action,传递到 reducer 中进行全局匹配,看哪一个 reducer 能够匹配这个action
         },
       };
    }
    

总结:用户 派发 action -> store 转发 action 到 reducer(不需要我们处理) -> reducer 根据 action 更新 state,并返回最新的 state -> store 将最新的 state 返回到组件的 props 中(不需要我们做) -> props 变化导致组件被渲染,更新页面。

  1. 异步 Action

    • 安装包 npm install redux-thunk
    • 修改 store.js 文件,让 store 能够使用这个 thunk 中间件处理异步请求
    import { createStore, applyMiddleware } from "redux";
    import thunk from "redux-thunk"; // 一个处理异步 action 的包
    // applyMiddleware(thunk): 让 store 对象使用中间件 thunk 来处理 action
    let store = createStore(reducer, applyMiddleware(thunk));
    
    • 在 action.js 中定义异步 action
     function saveUsers(list) {
       return {
         type: "SAVE_USERS",
         list,
       };
     }
    
     // 带有异步请求的 action:使用场景 多个组件都要向这个接口发请求,并且都要使用请求过来的数据。
     function queryUsers() {
       return (dispatch) => {
         axios.get("http://localhost:4000/users").then((res) => {
           // 请求成功的数据,要保存redux中
           // 通过派发 action ,让 store 去找相应的 reducer。
           dispatch(saveUsers(res.data));
         });
       };
     }
    
    • 在组件中,映射 reducer 和 异步请求的 action
    (dispatch) => {
     return {
       // 目的:在当前组件中映射一个方法,方法名称是 customChangeName。
       customChangeName(name) {
         dispatch(setName(name)); // 派发action,交给 store,store 对象会将 这个 action,传递到 reducer 中进行全局匹配,看哪一个 reducer 能够匹配这个action
       },
       queryUsers() {
         dispatch(queryUsers());
       },
     };
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值