react-redux学习笔记-2-react-redux

来源:互联网 发布:手机网络卡是怎么回事 编辑:程序博客网 时间:2024/05/22 16:42

1.前言

    本文简要介绍一下个人在做react-redux过程中的理解和demo解析。在阮一峰的教程 react-redux三部曲中对react-redux做了非常通俗易懂的讲解。但是在构建项目中还有一些细节问题需要考虑,有一些坑需要踩。因此本文将介绍一下自己的理解并给出一个可以运行的实例。

    本文首先介绍一下个人对react-redux的理解,然后说明一下使用react-redux构建项目的关键点。最后介绍一个实例。

2.react-redux的个人理解

    如果你熟悉react,那么你应该知道,这是一个以组件为核心的框架,它提供给我们构建组件的很方便的体验。我们可以通过改变组件的state去改变视图的展示。使用react创建组件,可以使我们不必关注DOM操作,只需要专注于业务逻辑,这极大地提高了代码的执行效率和代码的可维护、可读性。DOM操作是react替我们完成的,它根据组件state的变化去动态渲染DOM视图,也就是说,我们只需要把视图的变化进行抽象,对应到我们设计的组件的state,我们管理state就可以了。可是,如果项目的规模较大时,state的变化非常复杂,各个组件之间的通信逻辑将可能变得很难管理(实际上,react组件间通信应该仅限于父子间通信,父到子是传props,子到父是子调用父组件的回调。如果组件层级较多或者不是直系血亲,则应该使用其他机制进行通信管理)。react-redux就是帮助我们处理这种情况的。它使用状态机的思想,能让我们更加清晰地管理react组件的状态,并且可以方便清晰地进行组件间通信。

    react-redux的特点有以下这些:react-redux认为,一个应用就是一个状态机,视图触发状态的改变进而改变状态然后再刷新视图;react-redux认为,组件包括容器组件和UI组件。容器组件和UI组件有什么区别呢?简单地说,UI组件没有状态,当然也不需要改变状态,容器组件是有状态的。UI组件只根据父组件传过来的参数(props)去渲染不同的视图。容器组件是有状态的,状态在应用的整个生命周期中可能会发生改变,状态的改变应该导致容器组件的视图更新。react-redux为我们提供了由UI组件生成容器组件的API:connect,使用这个API可以由一个UI组件生成一个容器组件,这个容器组件负责管理状态并把状态传递到UI组件中以更新视图。因此,如果使用了react-redux,我们应该这样设计组件:如果你认为一个组件是容器组件,那么你需要写一个UI组件,这个UI组件根据props的数据渲染视图,并且它可以触发父组件(容器组件)状态的更新,然后使用connect生成一个容器组件;如果你认为一个组件是个UI组件,那么直接使用react写个组件就可以了。

    react-redux如何管理状态呢?我们知道,状态机包括state(状态),和action(活动),状态机运行时,先由初始state开始,每次触发一个action就会跳到下一个state。所以定义一个状态机需要知道 1.所有的state和 2.所有的action,并且要知道 3.处于每一个state时,触发任一个合法action将会跳向哪个state。下面介绍一下在使用react-redux搭建的项目中是如何定义这三方面内容的。1.怎样定义state?是通过store。store保存着所有的state,并且提供了可以更新state的API:store.dispatch。2.怎样定义action?react-redux中的action是一个对象,包含一个type字段和其它自定义字段。这需要我们自己定义。一般情况下我们会写一些action creater。3.怎样定义触发action的响应?用reducer,reducer定义了在处于某个state时,接到一个action应该跳到哪个state。定义好这三方面内容,其实就定义了一个可以正常运行的状态机,上面说到,react-redux不仅可以改变状态,还可以进行组件间通信,其实质也是触发action,一个组件可以触发其它组件的action,或者共享action,这样就可以进行通信了。使用react-redux完整构建一个项目应该包括以下关键点:

    首先,定义actionCreaters,然后定义组件,如果是容器组件,则定义一个UI组件(根据props渲染视图),再使用connect生成容器组件,connect的第一个参数是mapStateToProps,它返回一个对象,key是UI组件的props,value是容器组件的state,加上这个参数的话,该组件将会订阅store中相应的state,当state改变时,就可以重新渲染视图了,当一个组件在某种情况下需要知道其它组件的状态时,可以用这种方法订阅其它组件的state,第二个参数是mapDispatchToProps,如果不传改参数,将默认传store.dispatch到你的UI组件props中,这样在你定义的UI组件中就可以使用this.props.dispatch触发action了。定义好组件之后再定义reducer,reducer是纯函数,它根据你传来的action更新state。然后定义store,store的定义使用redux提供的 createStore API,它可以创建一个store实例,如果你需要异步触发action,那就要用到redux-thunk这个中间件,它允许你既可以定义返回对象的actionCreater也可以定义在其中dispatch(action)的actionCreater,这样你就可以在actionCreater中做一些异步操作了,比如等ajax返回了再dispatch一个action。最后,使用ReactDom.render将组件挂在到响应节点上,注意一般情况下我们需要使用Provider API将store传递下去。

3.demo

    下面介绍一下使用react-redux构建的一个demo

    除了需要安装react,redux等框架,还需要安装babel,因为我们使用了JSX和ES6/ES7的语法,因此需要在打包时进行转译。本地项目构建需要安装一系列框架和插件:

// 安装react和react-redux相关npm install --save-dev react react-dom redux react-redux redux-thunk// 安装babel核心库npm install --save-dev babel-core babel-loader// react用来解析JSX,es2015用来解析ES6,stage-0用来解析ES7npm install --save-dev babel-preset-react babel-preset-ex2015 babel-preset-stage-0// 安装其它loadernpm install --save-dev css-loader style-loader// 安装其它插件npm install --save-dev html-webpack-plugin extract-text-webpack-plugin
webpack配置如下:

var ExtractTextPlugin = require('extract-text-webpack-plugin');var HtmlPlugin = require('html-webpack-plugin');module.exports = {    entry: __dirname + '/game/main.js',    output: {        path: __dirname + '/public',        filename: 'main.js'    },    module: {        rules: [            {                test: /\.js$/,                use: {                    loader: 'babel-loader',                    options: {                        presets: ['es2015', 'react', 'stage-0']                    }                }            },            {                test: /\.css$/,                use: ExtractTextPlugin.extract({                    fallback: 'style-loader',                    use: 'css-loader'                })            }        ],    },    plugins: [        new ExtractTextPlugin('[name].css'),        new HtmlPlugin()    ]}
运行方式:执行

npm run build

然打开public文件中的index.html即可

demo地址:https://github.com/KIDFUCKER/react-redux-demo.git

分支: v2-react-redux