redux+react-redux+示例的快速上手体验

本文主要记录下本身在react道路上的爬坑过程 以及对于刚学习redux的同窗提供一些可供参考的例子。vue

以前用vue用了好久 vue的语法糖用起来是真的舒服 不过如今公司项目用的是react 只好默默的从vue转到react 其实毕竟他们都是相似的框架, 虽然语法大不一样, 可是有些地方的思想仍是很像的, 废话很少说了,开始正文...
本文主要分为两个部分:redux和react-redux。 首先大概过一下redux的基础部分:react

1.redux

要知道redux和react并无半毛钱的关系,redux甚至能够和jq一块儿用。 react-redux才是react的用于便捷操做redux的第三方插件。因此呢,学习react-redux以前咱们要比较熟悉的了解redux的思想。本文比较直接,不来虚的,直接上代码:
首先就很熟悉了
1 使用官方脚手架
create-react-app redux-demonpm

2 环境搭建好以后 继续安装redux
npm install redux --Sredux

进入到项目文件夹 把咱们用不到的全咔咔删掉浏览器

在src/index.js里引入redux并建立action reducer和store
src/index.js:app

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore } from 'redux' 
 
//这是redux的原始state
const tiger = 10000

//这是action
const increase = {
    type:'涨工资'
}
const decrease = {
    type:'扣工资'
}

//这是reducer
const reducer = (state = tiger, action) => {
    switch (action.type){
      case '涨工资': 
        return state += 100;
      case '扣工资': 
        return state -= 100;
      default: 
        return state;
    }
}

//建立store
const store = createStore(reducer);

console.log(store.getState())


ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

这里大概解释下每一个的意思:
action:行为 它是一个对象 里面必有type来指定其类型 这个类型能够理解为你要作什么,reducer要根据action的type来返回不一样的state 每一个项目有且能够有多个action
reducer: 能够理解为一个专门处理state的工厂 给他一个旧数据它会根据不一样action.type返回新的数据 也就是:旧state + action = 新state 每一个项目有且能够有多个reducer
store: store本质上是一个状态树,保存了全部对象的状态。任何UI组件都能直接的从store访问特定对象的状态。每一个项目有且只能有一个store
脑子里有了这些基本的概念后咱们就能够把reducer放到createStore里并建立好store了框架

能够看到 代码的最后咱们打印了store.getState() 这段代码简单理解就是打印下store里的数据
由于咱们只是写了action并无给它dispatch 因此reducer只会走默认的default 因此仅仅是返回state=tiger 那么tiger就是咱们以前定义好的state
此时咱们npm start 在浏览器打开该demo f12打开控制台 能够看到打印的数据为:10000
这里咱们只是简单的回顾下redux的基础知识 并无在app.js里面写任何东西dom

好 能够看到在上面咱们虽然定义了action 可是好像并无什么用啊? 接下来咱们要作的事情就是让它变化了。
刚才仅仅是得到到初始的数据 这并非咱们想要的结果 在实际项目中咱们确定有不少的需求 不一样需求对应不一样功能 不一样功能得到不一样数据,因此接下来咱们要用到dispatch给它派发不一样的action,上代码:
src/index.js:ide

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore } from 'redux' 
 
const tiger = 10000

//这是action
const increase = {
    type:'涨工资'
}
const decrease = {
    type:'扣工资'
}
//这是reducer
const reducer = (state = tiger, action) => {
    switch (action.type){
      case '涨工资': 
        return state += 100;
      case '扣工资': 
        return state -= 100;
      default: 
        return state;
    }
}

//建立store
const store = createStore(reducer);

//订阅事件
store.subscribe(() =>
  console.log(store.getState())
);

//派发事件
store.dispatch(increase)

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

能够看到, 打印的数据变成了 11000 也就是说reducer根据dispatch派发的action的type,return了新的state。固然咱们也能够派发store.dispatch(decrease) 那打印的结果就是 10000,缘由想必你们都知道。
其实咱们仅仅是多写了store.dispatch(increase) 和 store.subscribe(() =>{}) 他们的每一个做用大概解释下:
dispatch的做用就是告诉reducer 我给你action, 你要根据个人action.type返回新的state。 而后reducer就会根据action的type,返回新的state。
咱们给它dispatch了action,reducer也作出相应 最后也返回新的state 可是其实这时候console.log()不会打印新的数据 由于state虽然变化了 可是仍是打印store.getState()仍是原始的数据
这时候咱们就须要store.subscribe(() =>{})了 它的做用就是每当reducer返回新的数据 它就会自动更新页面 把UI组件的state更新下 否则的话 虽然state变化了 页面仍不会更新(虽然如今尚未其余组件)学习

2.react-redux

好了, 这些就是基本的redux的知识。咱们不难发现,这样其实挺麻烦的。你须要写好多好多东西,并且咱们并无把reducer,action什么的给分离出去,否则的话我还要往不少组件里面传不少东西。这对咱们实际开发是很不友好的。
因此, 这时候就十分迫切须要react-redux了。它的做用是帮助咱们操做redux。有了它咱们能够很方便的写redux。接下来上代码:

首先安装react-redux:

`npm install react-redux --S`
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';

class App extends Component {
    render() {
        const { PayIncrease, PayDecrease } = this.props;
        return (
            <div className="App">
                <div className="App">
                    <h2>当月工资为{this.props.tiger}</h2>
                    <button onClick={PayIncrease}>升职加薪</button>
                    <button onClick={PayDecrease}>迟到罚款</button>
                </div>
            </div>
        );
    }
}

const tiger = 10000

//这是action
const increase = {
    type: '涨工资'
}
const decrease = {
    type: '扣工资'
}
//这是reducer
const reducer = (state = tiger, action) => {
    switch (action.type) {
        case '涨工资':
            return state += 100;
        case '扣工资':
            return state -= 100;
        default:
            return state;
    }
}

//建立store
const store = createStore(reducer);

//须要渲染什么数据
function mapStateToProps(state) {
    return {
        tiger: state
    }
}
//须要触发什么行为
function mapDispatchToProps(dispatch) {
    return {
        PayIncrease: () => dispatch({ type: '涨工资' }),
        PayDecrease: () => dispatch({ type: '扣工资' })
    }
}

//链接组件
App = connect(mapStateToProps, mapDispatchToProps)(App)

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
)

咱们能够看到,咱们仅仅对代码进行了稍微的改造,在index.js里面写个APP组件以方便咱们观察,APP组件里面的button分别触发不一样的事件。
action啊 reducer啊 store啊 想必你们都已经了解过了 这里再也不作过多介绍。咱们主要关注下哪里有变化:
首先最明显的是demo中引入react-redux的Provider和connect,它们很是重要!这里先大概解释下它们的做用:
Provider:它是react-redux 提供的一个 React 组件,做用是把state传给它的全部子组件,也就是说 当你用Provider传入数据后 ,下面的全部子组件均可以共享数据,十分的方便。
Provider的使用方法是:把Provider组件包裹在最外层的组件,如代码所示,把整个APP组件给包裹住,而后在Provider里面把store传过去。注意:必定是在Provider中传store,不能在APP组件中传store。
connect:它是一个高阶组件 所谓高阶组件就是你给它传入一个组件,它会给你返回新的加工后的组件,注重用法倒简单,深究其原理就有点难度。这里不作connect的深究,主要是学会它的用法,毕竟想要深究必须先会使用它。首先它有四个参数([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]),后面两个参数能够不写,不写的话它是有默认值的。咱们主要关注下前两个参数mapStateToProps和mapDispatchToProps。
connect的使用方法是:把指定的state和指定的action与React组件链接起来,后面括号里面写UI组件名。

除此以外demo中还多出了mapStateToProps mapDispatchToProps 他们又有什么做用呢?通俗一点讲的话就是:
好比你在一个很深的UI组件里 当你想要得到store的数据就很麻烦。mapStateToProps就是告诉store你须要哪一个state,须要什么数据就直接在mapStateToProps中写出来,而后store就会返回给你。同理,若是你想要dispatch派发一些行为怎么办呢,mapDispatchToProps就是告诉store你要派发什么行为,须要派发什么行为就在mapDispatchToProps中写出来,而后store就会把你想要派发的行为告诉reducer,接下来你们都应该知道了 reducer就会根据旧的state和action返回新的state。

好了 , 这时候咱们npm start 打开浏览器看一下有什么效果:
图片描述

能够看到页面上已经有内容,多了一段文字和两个按钮,当咱们点击会有什么反应呢?
图片描述
果不其然,当咱们点击'升职加薪'按钮时候 '当月工资'也相应的增长了。咱们捋一下整个事件流程:
1 点击按钮 2 触发PayDecrease()方法 3 该方法派发相应action 4 reducer根据action的type响应获得新的state 5 经过{this.props.tiger}拿到新的state 渲染到页面

ok, 这个简单的demo咱们就实现了。可是如今还有一个问题:咱们把全部的action reducer store Provider connect等等都写在了一个页面,这在咱们实际开发中确定是不合理的,因此,咱们最后就给这个小demo再优化下:
首先,咱们要把action,reducer什么的抽离出去,做为一个单独的文件,而后再导出:
src/index.reducer.js:

const tiger = 10000

//这是action
const increase = {
    type: '涨工资'
}
const decrease = {
    type: '扣工资'
}
//这是reducer
const reducer = (state = tiger, action) => {
    switch (action.type) {
        case '涨工资':
            return state += 100;
        case '扣工资':
            return state -= 100;
        default:
            return state;
    }
}
export default reducer

其次,咱们也要把APP组件写在外面 (此处必定要注意: 导出的不是APP组件,而是connect后的APP组件)
src/APP.js:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class App extends Component {

  componentDidMount() {
    console.log(this.props)
  } 
  render() {
    const { PayIncrease, PayDecrease } = this.props;
    return (
      <div className="App">
        <h2>当月工资为{this.props.tiger}</h2>
        <button onClick={PayIncrease}>升职加薪</button>
        <button onClick={PayDecrease}>迟到罚款</button>
      </div>
    );
  }
}
//须要渲染什么数据
function mapStateToProps(state) {
  return {
    tiger: state
  }
}
//须要触发什么行为
function mapDispatchToProps(dispatch) {
  return {
    PayIncrease: () => dispatch({ type: '涨工资' }),
    PayDecrease: () => dispatch({ type: '扣工资' })
  }
}

export default App = connect(mapStateToProps, mapDispatchToProps)(App)

把这些东西分离出去以后,此时的index.js看起来明显就简洁了许多:
src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from './index.reducer'

//建立store
const store = createStore(reducer);


ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, 
    document.getElementById('root'));

好了,比较基础的redux和react-redux例子到这就结束了,感受废话有点多了。。能看完的都是真爱。。 哪有错误 欢迎指正!

相关文章
相关标签/搜索