Redux之action、store、reducer 使用

故事:其实自己天然的感觉react很难,所以一直没有入手去学习,同时感觉redux也是学习react里面比较难以理解的一部分(redux和react在技术上没有直接关系)


redux的核心概念

redux的核心概念就是store、action、reducer

store的创建

创建 store 文件夹, 接着在文件夹中创建 index.js

store/index

import { createStore } from 'redux'

import allReducer from '../reducers'
//创建了一个 store ,负责存储项目应用中的所有数据,传入两个参数 
// 参数1: reducer 用来修改state
// 参数2(可选): [], 默认的state值,如果不传, 则为undefined
const store = createStore(
    allReducer
);
export default store

复制代码

解释: createStore(reducer, [preloadedState], enhancer) 创建一个 Redux store 来以存放应用中所有的 state。 应用中应有且仅有一个 store。
store在这里代表的是数据模型,内部维护了一个state变量 store有两个核心方法,分别是getState、dispatch。前者用来获取store的状态(state),后者用来修改store的状态 ,store对象如下

{dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, Symbol(observable): ƒ}
dispatch: ƒ dispatch(action)
getState: ƒ getState()
replaceReducer: ƒ replaceReducer(nextReducer)
subscribe: ƒ subscribe(listener)
Symbol(observable): ƒ observable()
__proto__: Object复制代码

通过 store.getState() 可以获取当前store的状态(state) 

console.log(store.getState())  

 

通过 store.dispatch(action) 来达到修改 state 的目的 

 注意: 在redux里,唯一能够修改state的方法,就是通过 store.dispatch(action) 

store.dispatch({type: 'SETTHEME', themecolor: 'black'});

Provider

Provider在原应用组件上包裹一层,使原来整个应用成为Provider的子组件 接收Redux的store作为props,通过context对象传递给子孙组件上的connect 数据的获取是通过provider,将store里面的数据注入给组件。让顶级组件提供给他们的子孙组件调用

ReactDOM.render(
   <Provider store={store}>
      <BrowserRouter>
         {routes }
      </BrowserRouter>
   </Provider>,
    document.getElementById('app')
);复制代码

reducer的创建(reducer+actiocn+常量)

创建reducers文件夹,接着在文件夹中创建index.js

reducers/index

import { combineReducers } from 'redux';

import {theme} from './theme'
//合并reducers
export default combineReducers({
    theme
});
复制代码

reducers/theme

/*常量*/
const SETTHEME = "SETTHEME"

// 初始化状态
let initThemeState = {
    themecolor: "red"
}

//reducer reducer是一个纯函数。给定当前state树和要处理的action的函数,返回新的state树。
//reducer方法, 传入的参数有两个
//state: 当前的state
//action: 当前触发的行为, {type: 'xx'}
//返回值: 新的state
export function theme(state = initThemeState,action) {
    switch (action.type) {
        case "SETTHEME":
            return {
                ...state,//把数组展开合并
                themecolor:action.themecolor
            }
        default:
            return state
    }
}


// action 必须有一个type字段来标识这个行为的类型
export function setTheme(color) {
    return {
        type: SETTHEME,
        themecolor: color
    }
}

复制代码

reducer一个普通的函数,用来修改store的状态。传入两个参数 state、action 其中,state为当前的状态(可通过store.getState()获得),而action为当前触发的行为(通过store.dispatch(action)调用触发) reducer(state, action) 返回的值,就是store最新的state值

action对行为(如用户行为)的抽象,在redux里是一个普通的js对象 action必须有一个type字段来标识这个行为的类型

{ type: SETTHEME,themecolor: color }

mapStateToProps 与 mapDispatchToProps   与connect

import React, {PureComponent} from 'react'

import { connect } from 'react-redux'

import {BrowserRouter as Router, Route, Link} from 'react-router-dom'

class Product extends React.Component {
    constructor(props){
        super(props)
    }
    render() {
        console.log(this.props)
        return (
            <div className="product-main" style={{backgroundColor:this.props.themecolor }}>
                <div>这是产品页</div>
                <button onClick={this.props.setTheme.bind(this,"pink")}>
                    设置主题 pink
                </button >
                <div style={{marginTop:20 + 'px'}}> <Link to="/user">账户中心</Link></div>
            </div>
        )
    }
}
const mapStateToProps = (state) => {
    return {
        themecolor: state.theme.themecolor
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        setTheme(corlor) {
            const action = {
                type: "SETTHEME",
                themecolor:corlor
            }
            dispatch(action)
        }
    }
}
export default connect(mapStateToProps,mapDispatchToProps)(Product);

复制代码

react-redux 的另一个核心方法叫做connect 函数,,接受3个参数,一个 mapStateToProps 是把 Store 上的 state 映射为 props;另一个 mapDispatchToProps 则是把回调函数类型的 props 映射为派发 action 的动作,最后一个参数是连接的组件

connect 函数调用会产生一个『高阶组件』,一个高阶组件就是一个函数,它接受 React 组件为参数,返回一个新的 React 组件为结果。在上面的例子中,connect 产生的高阶组件产生了一个新的 React 组件 ,这个组件负责管理状态,而 Product组件是一个『傻瓜组件』,只负责渲染。

之前说 Provider 组件连接了 store , Provider 内部的组件有能力获取到 store ,是怎样获取的呢?就是通过 connect 这个方法获取到里面的数据的

如果需要对 store 的数据做修改,dispatch 是指的 store.dispatch ,可以通过 mapDispatchToProps 方法把 store.dispatch 挂载到props上,为什么呢? 因为想要改变 store 里的内容,就要调用 dispatch 方法, dispatch 方法被映射到了 props 上,所以就可以通过 this.props.dispatch 方法去调用了

<button onClick={this.props.setTheme.bind(this,"pink")}>
    设置主题 pink
</button >复制代码

@connect 装饰器

import React, {PureComponent} from "react"

import {BrowserRouter as Router, Route, Link} from 'react-router-dom'

import {connect} from 'react-redux'

import {setTheme} from "../../redux/reducers/theme"

@connect(state=> state.theme,{setTheme})
export default class User extends React.Component {
    constructor() {
        super()
    }
    render() {
        return (
            <div className="user-main" style={{backgroundColor:this.props.themecolor}}>
                <div>这是账户中心</div>
                <button
                   onClick={this.props.setTheme.bind(this,"blue")}>
                   设置主题 blue
                </button>
                <div> <Link to="/home">go首页</Link></div>
            </div>
        )
    }
}复制代码

Redux 中核心的 API 

createStore 可以帮助创建 store  

store.dispatch 帮助派发 action , action 会传递给 store store.getState 这个方法可以帮助获取 store 里边所有的数据内容 

store.subscrible 方法可以让让我们订阅 store 的改变,只要 store 发生改变, store.subscrible 这个函数接收的这个回调函数就会被执行

THE END
< <上一篇
下一篇>>