简单的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.datadefault:
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。