首先聲明: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 是一個高階函數
第一個參數