注1:本文主要根据 "自述|redux中文文档" 学习的个人总结记录。也是是为了更快更好的学习和接受redux的操作,更好的应用的项目中。原文档地址:http://www.redux.org.cn/
注2:本文较长,可能会需要花一点时间去阅读和理解.
之前我们大致的介绍了redux的基本概念,但是没有介绍如何结合到我们的应用中,这里简单介绍搭配React进行开发。
Redux和React之间并没有直接的关系,Redux支持React、Angular、Ember、jQuery 甚至纯 JavaScript。
尽管如此,Redux 还是和 React这类框架搭配起来用最好,因为这类框架允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。
这里用个人搭建的简单的React开发框架进行介绍一番~有什么建议希望大家多多提出~
一般在React中分为两种组件,分别叫做智能组件和笨拙组件,智能组件一般是最顶层的,通过路由进行控制,redux也是通过智能组件进行注入。笨拙组件一般都是智能组件的子组件,关于store中的数据都是通过智能组件中props进行注入。如下图查看区别:
接下来看下整个项目的文件目录结构:
components文件夹中会分为多个子文件夹,每个文件夹分别表示的是应用中的每一个页面。redux文件夹中分别放我们的action,reducer以及后面要说的关于对异步action的配置。
router文件夹中存放的是我们对路由的控制。
- 如何将我们的应用连接到Redux ?
npm install react-redux
我们应该在组件的最顶层连接redux,另底层组件可以dispatch action以及从redux store中读取state.
首先我们要获取从之前安装好的React-redux中提供的Provider,在渲染之前把根组件包装进去。
如图,因为结合了React-router,它可以控制应用的视图和数据流。因为React-router渲染的是从根组件开始,所以我们用Provider把它包装进来就可以了,这样就可以在下面的组件中使用store。
接下来,我们需要通过redux-react提供的connect方法将包装好的组件连接到redux。注意,一般我们只会在顶层组件(也就是智能组件)中使用connect方法,因为这样会很方便的知道你的数据流是从来哪里开始进来的,如果你在每个组件里都使用了connect方法,这样数据的入口就不止一个,对于庞大的应用到最后会容易混淆。
对于使用connect方法包装后的组件,都会得到一个dispatch方法作为组件的props,以及全局state中的内容。
connect方法的参数是一个selector函数,这个selector函数可以接受到全局的state,然后返回组件需要的state。这样说大家可能云里雾里,看下图以及图中注释相信大家一定会明白的。上面那个截图中,我们通过provider注入了store,接下来:
我们在根组件中使用了connect方法连接redux和顶层组件(HomePage.jsx),在connect中传入了select函数,select函数是会接受到全局的state,然后根据我们的需要return出state。
基本上在React应用中使用redux就是如此简单,但是我相信还是有很多人有很多的迷惑,那么我根据自己在学习中的遇到的疑惑总结如下几点:
1. store从哪里来的?
答:之前说过,我们会根据应用将reducer拆分成多个子reducer,然后通过redux提供的combineReducers将所有的reducer合并成一个根reducer。最后通过createStore方法创建一个redux store。
//rooterReducer.js 文件 import {combineReducers} from 'redux'; import * as demoReducer from './demoReducer.js' const rootReducer = combineReducers({ ...demoReducer }); export default rootReducer; //然后如下创建redux store import rootReducer from 'rooterReducer.js' const store = createStore(rootReducer)
2. store怎么注入到组件中?
答:上面说了store是通过Provider注入到组件中的。
import rootReducer from 'rooterReducer.js' const store = createStore(rootReducer) ReactDOM.render( <Provider store={store}> <Router history={browserHistory} routes={router} /> </Provider>,document.getElementById('app') )
3. 通过connect连接的组件中如何获取到全局state?
答:connect方法中可以传入一个selector函数,这个函数可以获取到全局的state。
//假设是通过上面两个问题中的方法创建redux store和传入store function select(state) { console.log(state,'state') //{ demoReducer: {} } "state" return state } export default connect(select)(HomePage)