首先声明:redux仅仅做为数据层框架,与react没有直接的联系,他能够应用与angular等其余视图层框架,或者直接导入使用react
redux核心分为三部分:npm
store: redux的核心,暴露一些方法:getState() dispatch() subscrible(),store在整个应用中是惟一的,而且不能直接被修改,必须经过reduce修改redux
reduce:指定了应用状态的变化如何响应 actions 并发送到 store 的浏览器
action:一个纯JS对象,用来告诉reduce应该如何改变state,多数状况下,会有一个 type 值,且会被定义成字符串常量并发
实例:框架
index.jsdom
import { createStore } from 'redux' import reduce from './reduce' const store = createStore(reduce, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) export default store
第二个参数ide
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()函数
是给Redux开发者工具使用,添加后浏览器图标会激活工具
reduce.js
const defaultState = { data: [ 'Racing car sprays burning fuel into crowd.', 'Japanese princess to wed commoner.', 'Australian walks 100km after outback crash.', 'Man charged over missing wedding girl.', 'Los Angeles battles huge wildfires.' ] } export default function reducer(state = defaultState, action){ switch (action.type) { case 'ADD_RECORD': return Object.assign( {}, state, { data: [...state.data, action.text] } ) case 'DEL_RECORD': var data = [...state.data] data.splice(action.index, 1) return Object.assign( {}, state, { data } ) default: return state } }
每当调用store的dispatch方法,会执行reduce函数,reduce要求咱们返回一个state,reduce中有如下注意点:
Date.now()
或 Math.random()
action
export const addRecord = function(text){ return { type: 'ADD_RECORD', text } } export const delRecord = function(index){ return { type: 'DEL_RECORD', index } }
在须要修改store状态的组件中触发reduce修改state
import store from './store' import { addRecord } from './store/action' class Mycomponent extends Component { ... addRecord(){ //调用 dispatch ,参数为一个 action store.dispatch( addRecord(this.state.inputVal) ) } ... }
在调用store组件订阅store,实时响应
import store from './store' class MyList extends React.Component{ constructor(props){ super(props) this.state = { ...store.getState() } store.subscribe(() => { this.setState({ ...store.getState() }) }) } ... }
reacte-redux
以上这种动手订阅的方式十分繁琐,所以推荐使用专为react打造的第三库 react-redux 去链接redux
使用:
npm install react-redux --save
在index.js文件中引入 Provider 组件,将它包在最外层,把 store 做为 prop 传入 Provider
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; import { Provider } from 'react-redux' import store from './store' const Application = ( <Provider store={store}> <App /> </Provider> ) ReactDOM.render(Application, document.getElementById('root'));
在应用组件中经过 connect 将组件与 store 关联起来,而后能够经过直接访问 props 的方式访问 store
import React from 'react' import { connect } from 'react-redux' import { delRecord } from './store/action' class MyList extends React.Component{ render(){ return ( <ul className="list-container"> {this.props.data.map((item, index) => ( <li key={index} onClick={() => { this.props.delRecord(index) }}>{item}</li> ))} </ul> ) } } const mapStateToProps = (state) => ({ ...state }) const mapDispatchToProps = (dispatch) => ({ delRecord(index){ dispatch(delRecord(index)) } }) export default connect(mapStateToProps, mapDispatchToProps)(MyList)
其中 connect 是一个高阶函数
第一个参数