简单的redux示例:

// 第一步 定义计算规则,即 reducer
function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

// 第二步 根据计算规则生成 store
let store = createStore(counter)

// 第三步 定义数据(即 state)变化之后的派发规则
store.subscribe(() => {
  console.log('current state', store.getState())
})

// 第四步 触发数据变化
store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'DECREMENT'})

第一,要通过一个函数来触发数据的变化,即dispatch,触发的时候一定要符合之前定制的规则,否则无效。第二,数据一旦发生变化时,会导致怎样后果,即subscribe中定义的函数会执行。第三,如何取得当前的数据,即store.getState()

1、定义reducer

  • 定义具体规则 userinfo

 

  import * as actionTypes from '../constants/userinfo'

  const initialState = {}

  export default function userinfo(state = initialState, action) {
    switch (action.type) {
    // 登录
    case actionTypes.USERINFO_LOGIN:
      return action.data

    // 修改城市
    case actionTypes.UPDATE_CITYNAME:
      return action.data

    default:
      return state
    }
  }

 

  • 对所有的reducer 封装,对外提供统一的接口

   import { combineReducers } from 'redux'

   import userinfo from './userinfo'

  const rootReducer = combineReducers({
    userinfo
  })

 

 

       export default rootReducer

 

2、定义store

  import { createStore } from 'redux'
  import rootReducer from '../reducers'

  export default function configureStore(initialState) {
    const store = createStore(rootReducer, initialState,
      // 触发 redux-devtools
      window.devToolsExtension ? window.devToolsExtension() : undefined
    )
    return store
  }

3、结合react,程序的入口文件app/index.jsx

import { Provider } from 'react-redux'
import configureStore from './store/configureStore'

import Hello from './containers/Hello'

const store = configureStore()

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

store通过 react-redux的Provider组件派发到Hello组件中

4、定义action,action是行为的抽象,必须有一个type属性

export function login(data) {
  return {
    type: actionTypes.USERINFO_LOGIN,
    data
  }
}

export function updateCityName(data) {
  return {
    type: actionTypes.UPDATE_CITYNAME,
    data
  }
}

  

5、Hello组件中使用reducer和action

  • 将reducer和action当作props传入到Hello中

     import * as userinfoActions from '../actions/userinfo'

  function mapStateToProps(state) {

    return {
      userinfo: state.userinfo
    }
  }

  function mapDispatchToProps(dispatch) {
    return {
       userinfoActions: bindActionCreators(userinfoActions, dispatch)
    }
  }

  export default connect(
    mapStateToProps,
    mapDispatchToProps
  )(Hello)

  • Hello中通过this.props.userinfo和this.props.userinfoActions获取数据和action

  class Hello extends React.Component {

    render() {
      return (
         <div>
            <p>hello world</p>
            <hr/>
            <A userinfo={this.props.userinfo}/>
            <hr/>
            <B userinfo={this.props.userinfo}/>
            <hr/>
            <C actions={this.props.userinfoActions}/>
        </div>
      )
  }
  componentDidMount() {
    // 模拟登陆 此处会触发数据变化,aciton中login的type对应reducer中的type,然后reducer响应type的操作是返回data,然后派发规则mapStateToProps,返回数据到props中。

    this.props.userinfoActions.login({
        userid: 'abc',
        city: 'beijing'
      })
    }
  }

   

mapStateToProps 如果这个没有传这个参数,那么组件就不会监听Redux store.

其实原因很简单,由于connect中只有mapStateToProps(state, [ownProps])是根据redux store state的改变进行改变的,而像mapDispatchToProps(dispatch, [ownProps])mergeProps(stateProps, dispatchProps, ownProps)都和redux store无关,所以如果mapStateToProps没有传的话,就不需要去监听redux store。