资讯专栏INFORMATION COLUMN

react-redux初级教程,纯白话讲述redux数据、开发流程整理,redux数据持久化实现

gclove / 3072人阅读

摘要:日常项目直接使用是完全没有问题的,可是随着项目的日益壮大,组件数量的逐渐增长,组件之间的嵌套使得数据的管理越来越繁重。最后数据保存进了中的,页面也会根据的改变自动更新。

以下文章均为个人近期所学心得,自学react、redux,逐渐找到自己的方向,现将自己的方向方式写出来,以供大家学习参考,肯定会有不足,欢迎批评指正。

日常项目直接使用react是完全没有问题的,可是随着项目的日益壮大,组件数量的逐渐增长,组件之间的嵌套使得数据的管理越来越繁重。
纯react项目,每个组件自己维护自己的state,父子组件之间通信、兄弟组件通信也都可以做到,只不过随时项目代码量的增加后期会变得难以维护,所以使用redux这种数据管理是很有必要的,而且也是自我技术水平提高的一个很好方向。

本文专注功能实现、使用流程,所以可能细节问题点阐述的不够深,不过个人觉得用于初学者使用并且达到想要的功能应该可以满足了。

首先原理(纯白话):
页面操作(点击啊什么的)触发action -->
action做一层处理后触发reducer -->
reducer中定义全局的唯一的store中的state+存入的方法(必须是纯函数,也就是说你传入什么参数就输出相应的结果,不可以根据实时时间戳啊等类似的方法产出不同的值。) -->
最后数据保存进了store中的state,页面也会根据state的改变自动更新。

基本:
Provider:具体概念不赘述,想细研究的自行度娘,这里只说明放在根组件的最外层并将store传递进去
    
        
    

代码(登录功能流程):

// 使用react-redux中的connect方法
import { connect } from "react-redux";
// 导入我们定义的action
import { saveUserinfo } from "@/Reducers/Pages/actions";
// 使用connect包裹我们的state和action,这里有两个方法(mapStateToProps、mapDispatchToProps),具体概念自行度娘
// 组件结尾导出处
export default connect(mapStateToProps, mapDispatchToProps)(Login);
// 可以写成
export default connect(state => ({
    // 如果你的组件需要使用store中的state,就在这里引入你所以要使用的reducer函数名
}), {
    // 这里引用你当前组件所需要使用的所有action方法
    saveUserinfo
})(Login);

// 按钮提供一个点击事件


// sumitForm方法
sumitForm = () => {
    var username = this.refs.username.value;
    var password = this.refs.password.value;
    // 发送ajax请求,这里我封装一层,很简单,可以直接写ajax请求,主要点在请求成功的回调里
    LoginFunc(username,password)
        .then(res => {
            // 请求成功后的数据
            var data = res.data;
            // 这里就是触发action的地方,只需要将我们需要的数据作为参数传进去就好
            this.props.saveUserinfo(data);
            this.props.history.push("/index");
        })
}

以上就是我们在组件中触发action的过程,到这里你就可以将接口返回来的数据传递给action了

// 定义action时需要先定义action-type,作用就是关联action和reducer,action想要触发reducer那么只需要使用定义的type就可以,不需要去引用reducer,这样别人在看我们的代码时,看type就知道这一块有哪些功能了,具体的注释也可以写在type中。
// type很简单
// 保存用户信息
export const SAVEUSERINFO = "SAVEUSERINFO";

action代码

// 导入type
import * as Pages from "./action-types";
// 保存用户表单数据
export const saveUserinfo = (data) => {
    // 这个传进来的data就是我们刚刚在组件中传递进来的后端返回数据
    // 这里直接returntypes,并将data传递过去
    return {
        type: Pages.SAVEUSERINFO,
        data
    }
}

这里就是action,我们可以将组件中的后端请求写在action里,只需要返回的时候触发type并将数据传递过去就好

下面我们看reducer

// 之前说了,action只需要触发type就可以触发reducer了
// 所以reducer中同样需要引入reducer
import * as Pages from "./action-types";
// 在reducer中我们需要定义state,也是就是唯一store中的state
let defaultValue = {
    session_id: "",
    user_name: "",
    user_id: "",
    is_login: false,
    initialization: "",
    org_name: ""
}
// reducer中就是将action传递过来的数据保存到store中的state里
// 两个参数,第一个是state,第二个是action传递过来的数据,包含type和数据,通过type值判断执行那个函数,这里只定义了一个type
export default function UserInfo (state = defaultValue, action = {}) {
    switch (action.type) {
        // 这个就是type也就是action和reducer关联的type
        case Pages.SAVEUSERINFO:
            return { ...state,
                // 这里就是将action传递过来的数据保存到我们的store中
                ...{
                    session_id: action.data.data.session_id,
                    user_name: action.data.data.name,
                    user_id: action.data.data.id,
                    is_login: true,
                    initialization: action.data.data.initialization,
                    org_name: action.data.data.org_name
                }
            };
        default:
            return state;
    }
}

以上就完成了我们从后端拿数据,保存到store中的所有流程。

// 保存到了store中后,我们页面的所有组件都可以拿这里边的数据,
// 同样,我们组件中用到数据的地方会根据store中数据的改变而改变,也就是说我们想要改变页面的状态,唯一的办法就是触发action完成以上步骤。

到这里我们还没有结束,需要我们形成闭环,也就是怎么将store存入我们的Provider

// 我这里是将store拆分了,按功能去拆分的,具体可以看每个人的习惯去拆分

我的目录结构,可根据具体项目区自定自己的目录结构

// 有拆分就要有合并,所以我们要在存入Provider之前进行reducer的合并
// 这里使用redux提供的方法combineReducers
import {
    combineReducers,
} from "redux";
import UserInfo from "./Pages/reducers";
const rootReducer = combineReducers({ 
    UserInfo,
    // 一些其他功能的reducer
    // UserStaffDirectory,
    // addUserMsgReducer
});
// 导出统一的reducer
export default rootReducer;

插一句,以上就已经完成了基本功能,这里我在多加一项功能,就是数据持久化,也就是我们数据存到store中但是会存在一个刷新数据丢失的问题,这样很不利与我们项目的使用,所以我加入一个新的库,来保证我们的数据是可持久化的,这里使用redux-persist库
数据持久化

// 首先导入redux的一些方法
import {
    createStore,
    applyMiddleware
} from "redux";
// 还使用了thunk,还没来的及去研究,这里先使用吧
import thunk from "redux-thunk";
// 引入redux-persist
import { persistStore, persistReducer } from "redux-persist";
import { PersistGate } from "redux-persist/es/integration/react";
import storage from "redux-persist/es/storage"
// 首先定义一个对象(按官方文档来的,没具体研究)
const persistConfig = {
    key: "root",
    storage,
};
// 将我们的合并后的reducer引入
import Reducers from "@/Reducers";
// 使用redux-persist合并
const persistedReducer = persistReducer(persistConfig, Reducers)
// 定义一个函数,返回persistor和store,让我的组件使用
function configureStore(){
    // 这里我使用了thunk,具体原理我也没去细研究,使用redux的createStore去合并,最终产出我们需要传入Provider的store
    let store = createStore(persistedReducer, applyMiddleware(thunk));
    // 这里就是应用redux-persist以完成数据持久化
    let persistor = persistStore(store);
    return { persistor, store }
}
// 组件render中
const render = Component => {
    // 引入
    const { persistor, store } = configureStore();
    ReactDOM.render(
        // 将store传入跟组件
        
            // 数据持久化
            
                // 所有子组件
                
            
        ,
        document.getElementById("app"),
    )
}

以上就完成了全部循环,组件发起action,触发reducer,保存数据到store中,组件被更新。

只有存的步骤,不能没有取,对吧,上文中实现了登录功能,并且将后端返回的数据保存到store中,现在我们将store中的数据拿出来展示在界面上。
登录请求成功后后端会返回用户名,用户ID等信息,我们已经将其保存到了store中,下面看我们的header组件将引用我们store中的用户名。

不需要我们引入过多的文件,只需要在组件结尾处的方法mapStateToProps加入我们要的reducer函数名即可

const mapStateToProps = state => ({
    UserInfo: state.UserInfo
})
export default connect(mapStateToProps,({}))(Header);
// 组件中使用
this.props.UserInfo.user_name
// 即可取值
// 同时呢,我们改变了store中的user_name那么我们取值的地方也会动态更新。

以上就是本文全部内容,如有发现不足,或错误之处,烦请指正。
转载请注明出处,SF大洋首发。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96726.html

相关文章

  • 实例讲解react+react-router+redux

    摘要:而函数式编程就不一样了,这是模仿我们人类的思维方式发明出来的。数据流在中,数据的流动是单向的,即从父节点传递到子节点。数据流严格的单向数据流是架构的设计核心。 前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应用的过程。 代码地址:Re...

    RiverLi 评论0 收藏0
  • Redux入门教程(快速上手)

    摘要:接下来演示不变性打开终端并启动输入。修改代码如下我们使用在控制台中打印出当前的状态。可以在控制台中确认新的商品已经添加了。修改和文件最后,我们在中分发这两个保存完代码之后,可以在浏览器的控制台中检查修改和删除的结果。 典型的Web应用程序通常由共享数据的多个UI组件组成。通常,多个组件的任务是负责展示同一对象的不同属性。这个对象表示可随时更改的状态。在多个组件之间保持状态的一致性会是一...

    amuqiao 评论0 收藏0
  • 实例讲解基于 React+Redux 的前端开发流程

    摘要:宅印前端基于的模式开发,我们指定了一套分工明确的并行开发流程。下面通过一个苹果篮子实例,来看看整个应用开发流程。容器负责接收中的和并发送大多数时候需要和直接连接,容器一般不需要多次使用,比如我们这个应用的苹果篮子。 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 star 数达 42000 +,超过了 jquery 的 39000+,...

    chaosx110 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<