今天我们来聊聊Redux,这篇文章是一个进阶的文章,建议大家先对redux的基础有一定的了解,在这里给大家推荐一下阮一峰老师的文章: http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

对于基础部分我在这里稍微讲解一下

  首先我们要知道我们为什么要使用Redux,我们在什么情况下才需要去使用Redux,在这里引用Redux的创造者的一句话:"只有遇到 React 实在解决不了的问题,你才需要 Redux 。" 

  结合项目经验说下我自己的理解:如果这批数据只是在一个组件使用并且不需要和别的组件进行数据共享,从单一来源获取数据的时候,也就是说你的UI层很简单,没有复杂的数据流动,总之就是加入数据流动单项并且很简易,没有与服务器的大量交互的情况下,我们不需要使用Redux,否则只会让我们的开发变得更加复杂。

  那么什么时候我们需要用到Redux呢:比如你的数据流动很复杂,这批数据有多个组件需要使用甚至别的页面也需要使用它,或者说就是你的某些状态需要在多个没有强关联的组件中用到,举个很常见的例子,就比如说我们做登录保存用户信息或者是做购物车的时候,我们就很有必要引入Redux来帮我们做状态管理了,总之,就是在你某些状态或者数据的很难控制很难传递的时候,你需要Redux来帮助你。

参照这张经典图来讲解一下Redux的工作原理

  组件Component通过ActionCreators派发一个行为action(注意在这里是派发一个扁平对象),这个行为被派发到了Store,Store借助Reducer确认该State的状态并执行相应的操作,接下来Reducer把新的State返回给Store,最后Store把这个State转给了Component。

假如说你已经在你使用Redux做过一些小demo了,我讲一下在项目中的一个Redux进阶用法,我就根据上面讲的Redux的工作流程,结合伪代码给大家讲解一下在项目中我们应该如何去使用它(建议把这段伪代码通读几遍,因为本人写的前后顺序排的不是很合理,但是通读下来几遍的话,相信你能理解的):

  第一步:我们要在最外面注册一个Store

import { createStore, applyMiddleware } from 'redux'    //applyMiddleware作用是提供一个中间件,关于Redux中中间件的理解大家可以去官网看一下,很有用处,链接地址:http://cn.redux.js.org/docs/advanced/Middleware.html
import thunk from 'redux-thunk' //可以让dispatch传的内容就不会局限于只能传一个扁平对象了,就可以传一个函数了,关于redux-thunk的话后期我给大家写一个它源码的解析,最近太累了,感兴趣的伙伴先自己查查
import reducers from './reducers'   const store = createStore(reducers,applyMiddleware(thunk))    export default store

  第二步:可能你会有很多个地方要用到Redux,那么你可能会有很多reducer,这个时候我们会需要redux提供的combineReducers来将我们各个地方的reducer进行合并,就会让它们互不影响

import { combineReducers } from 'redux' //为了可以引入多个reducer

//以下是伪代码,只是模拟我们有多个reducer,我们可以把它们合并起来,互不影响
import {reducer as first} from 'pages/first'
import {reducer as ticket} from 'pages/ticket' export default combineReducers({
first,
ticket
})

  第三步:全局注入store

import { Provider } from 'react-redux'    //你可以Provider想象成一个注入器,它可以帮我们把store注入到我们的根组件上,这样的话store将无处不在
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

  接下来就是我们某个地方要如何使用Redux,假设现在的场景是这样的,我们要派发一个action,同时这个action还要去请求ajax,ajax又是异步的,这个时候我们刚才的那个thunk就有作用了,我先简单讲解一下它的作用,我们通常情况下是提交一个扁平对象,然后这个action直接送到reducer中去进行操作,但是我们有异步请求数据的时候怎么办呢,thunk给我们提供的就是我们派发行为的时候可以派发一个函数,再派发一个扁平对象,当遇到函数的时候会先执行函数里面的内容最后再去提交到reducer中,好,大概你应该懂我的意思了,开始操作:

 

第四步:我们要触发action对吧,为了避免命名冲突,我们先来创建一个actionTypes.js文件,我们要给每个type加一个命名空间:

export const GET_COMMENT_DATA = 'ticket/get_comment_data'

export const SET_RECORD_DATA = 'ticket/set_record_data'

  

  第五步:我们要去派发一个action,直接把怎么拿store中的数据也写出来把

const mapDispatch = (dispatch)=>{
return {
loadList(){
dispatch(loadListDataAsync(dispatch))
}
}
}
const mapState = (state) => {
return {
swiperList: state.first.list
}
}

  

  第六步:我们要从react-redux中引入一个connect,它是帮助我们来可以在组件中使用dispatch和state的,写法是这样的:

export default connect(mapState,mapDispatch)(App)
记录下我之前遇到的一个小坑,之前我是只在当前组件中用到了dispatch,所以我是这样写的:
export default connect(mapDispatch)(App)      //后来发现会有一堆红色的怪物包围着我
正确的姿势其实是这样的:
export default connect(null,mapDispatch)(App)

  

  第七步:我们去看看我们是怎么利用thunk请求ajax数据的把:

import { GET_COMMENT_DATA } from './actionTypes'

export const LoadCommentDataAsync = (dispatch,id)=>{        
return ()=>{              //在这个函数中我们可以进行异步请求数据
fetch('/haha', {
method: 'GET',
headers: {
'content-type': 'application/json'
},
})
.then(response => response.json())
.then(result=>{
dispatch({            //遇到扁平对象了,可以提交到reducer了
type: GET_COMMENT_DATA,
comments: result
})
})
}
}

  

  第八步:我们来到reducer中处理你的action

import { GET_COMMENT_DATA } from './actionTypes'
import { SET_RECORD_DATA } from './actionTypes' const defaultState = {
comments: {},
records: []
} export default (state=defaultState,action)=>{
if(action.type === GET_COMMENT_DATA){
return {
...state,
comments: action.comments
}
}
if(action.type === SET_RECORD_DATA){
return {
...state,
records: [...state.records,action.records]
}
}
return state
}

  

  第九步:我们把这个reducer暴露出来,也就是我们第一步在reducers中引入的reducer

import reducer from './reducer'

export {
reducer
}

   这篇写的不是很好,原谅我,最近很多事都堆在一起了,等我调整好了,这次的代码就当成全是伪代码来看,重在理解Redux的流程以及它是如何在项目中进行使用的,理解它的用法即可,相信你看懂了以后在写项目的时候会对它的理解会越来越深刻的,别看我代码是怎么写的,就看看步骤就行了,我承认这次写的很烂(:,等我调整好了给大家把注释和解释再完善完善,后期我会来修改它的

理解Redux以及如何在项目中的使用的更多相关文章

  1. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  2. 教你如何在React及Redux项目中进行服务端渲染

    服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...

  3. 理解java Web项目中的路径问题

    本文以项目部署在tomcat服务器为例,其他相信也是一样的. 先说明请求页面的写法,在web中,页面路径主要写的有以下几种 1.请求重定向 2.浏览器的请求被服务器请求到新页面(我称为“转发”) 3. ...

  4. .NET抽象工厂模式微理解--教你在项目中实现抽象工厂

    .NET抽象工厂模式微理解--教你在项目中实现抽象工厂 最近在学习MVC,对于MVC里面的一些项目上的东西都和抽象模式有关,今天就微说明一下个人对于抽象工厂模式的理解,以方便学习MVC及工厂模式相关的 ...

  5. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  6. 你真的理解 Spring Boot 项目中的 parent 吗?

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent> <groupId ...

  7. SLAM+语音机器人DIY系列:(二)ROS入门——8.理解roslaunch在大型项目中的作用

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  8. 记录ThreadPoolTaskExecutor线程池的在项目中的实际应用,讲解一下线程池的配置和参数理解。

    前言:最近项目中与融360项目中接口对接,有反馈接口(也就是我们接收到请求,需要立即响应,并且还要有一个接口推送给他们其他计算结果),推送过程耗时.或者说两个接口不能是同时返回,有先后顺序. 这时我想 ...

  9. 理解JavaWeb项目中的路径问题——相对路径与绝对路径

    背景: 在刚开始学习javaweb,使用servlet和jsp开发web项目的过程中,一直有一个问题困扰着我:servlet 和 jsp 之间相互跳转,跳转的路径应该如何书写,才能正确的访问到相应的s ...

随机推荐

  1. SQL点点滴滴_常用函数

    该文章转载自http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 别人的总结,很详细. 以下所有例子均Studnet表为例 ...

  2. Linux 学习笔记之关机问题

    在linux领域内大多用在服务器上,很少遇到关机的操作. 正确的关机流程为:sync > shutdown > reboot > halt 关机指令为:shutdown ,你可以ma ...

  3. linux下生成带符号的随机密码

    cat /dev/urandom |tr -dc "[:graph:]"|fold -w 15|head 结果如下:

  4. Hadoop学习---Eclipse中hadoop环境的搭建

    在eclipse中建立hadoop环境的支持 1.需要下载安装eclipse 2.需要hadoop-eclipse-plugin-2.6.0.jar插件,插件的终极解决方案是https://githu ...

  5. RedHat(Linux) Oracle数据库设置开机自启动

    1 首先修改/etc/oratab文件添加如下行:ycr:/u01/app/oracle/product/12.1.0/dbhome_1:Y 关于/etc/oratab文件解释如下:# This fi ...

  6. mysql 修改已存在的表增加ID属性为auto_increment自动增长

    今天有需要将已经存在表设置自动增长属性 具体如下 alter table customers change id id int not null auto_increment primary key; ...

  7. mongodb启动和关闭

    mongodb的启动 mongod --dbpath=/data/mongodb/data --logpath=/data/mongodb/log/33988.log --port 33988 --f ...

  8. PopupWindow学习笔记

    最近写程序第一次用到了PopupWindow,便简单了学习了一下.特此记下自己的收获.PopupWindow是一种悬浮框,比AlertDialog要灵活的多.先简单了实现一个PopWindow的效果, ...

  9. 牛客网多校训练第一场 A - Monotonic Matrix(Lindström–Gessel–Viennot lemma)

    链接: https://www.nowcoder.com/acm/contest/139/A 题意: 求满足以下条件的n*m矩阵A的数量模(1e9+7):A(i,j) ∈ {0,1,2}, 1≤i≤n ...

  10. Thread-Specific-Storage for C/C++

    引用出处:https://www.cse.wustl.edu/~schmidt/PDF/TSS-pattern.pdf 摘要: 理论上多线程会提高程序性能,但实际上,由于在获取和释放锁的开销,多线程经 ...