一:調試javascript
注意:Redux調試工具。谷歌中搜redux同理reacthtml
新建store的時候判斷window.devToolsExtension
使用compose(組合函數)結合thunk插件和window.devToolsExtensjava
二:Reduxreact
Redux 是 JavaScript 狀態容器,專一於狀態管理的庫npm
總體來講是單一狀態。就是指的是單向的數據流json
應用中全部的 state 都儲存在 store 中。 唯一改變 state 的辦法是dispatch觸發 action,爲了描述 action 如何改變 state ,須要編寫 reducer。redux
redux中最重要的幾個:store state action reducer緩存
首先安裝redux 安裝:http://www.cnblogs.com/kelly2017/p/7930681.htmlapp
package.json中有dom
react-redux把狀態映射到子組件 分發reducer
redux 建立reducer action store等
react-thunk thunk處理髮送請求異步。
import { createStore } from 'redux';
//新建一個store
//經過reducer來創建,是個形式爲 (state, action) => state 的純函數。
//reducer描述了 action 如何把老的狀態state和action 生成新的狀態state
// action有type
function couter(state=0, action) {
switch (action.type){
case '加':
return state+1
case '減':
return state-1
default:
return 1
}
}
const store=createStore( couter )
//1: 建立 Redux store 來存放應用的狀態(根據reducer來建立)
// store 應用中全部的 state 都儲存在一個單一的 store 中。
const init=store.getState()
//store.getState()隨時獲取最新的狀態
console.log(init)
//派發事件
//須要狀態變動的時候 store.dispatch(action)來提交狀態變動
//改變內部 state 唯一方法是 dispatch 一個 action。
store.dispatch({type:'加'})
//console.log(store.getState())
store.dispatch({type:'加'})
//console.log(store.getState())
store.dispatch({type:'減'})
//console.log(store.getState)
function listener() {
const current=store.getState()
console.log(`如今的總數是${current}`)
}
store.subscribe(listener)
//subscribe 訂閱事件
//store.subscribe來監聽每次state修改
//每次dispatch都會執行listener
運行結果:
2:Redux和React
redux和react一塊兒結合使用的方法:
1)
由於改變內部 state 唯一方法是 dispatch 一個 action。
因此把store.dispatch的方法傳遞給組件,使其內部能夠調用修改狀態
react的修改狀態從以前的setState({})變成了由store來統一管理
2)
store.subscribe來監聽每次state修改
每次dispatch都會執行訂閱的事件
subscribe來定義render函數,每次修改都從新渲染頁面。
3)
react和redux的文件分離
index.js中 建立store
訂閱subscribe只要狀態改變。就從新渲染頁面 render()
const store=createStore(couter)
新建store.以組件屬性的形式。添加到component組件裏
經過subscribe訂閱這個render函數,狀態有變化。render就會從新渲染頁面
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import App from './App';
import { couter,addFn,minusFn } from './index.redux';
import registerServiceWorker from './registerServiceWorker';
const store=createStore(couter)
function render() {
ReactDOM.render(<App store={store} addFn={addFn} minusFn={minusFn}/>, document.getElementById('root'));
}
render()
store.subscribe(render)
registerServiceWorker();
新建index.redux.js專門管理redux
存放reducer和 dispatch的action //store.dispatch({type:'加'});
//經過reducer來創建。
const ADD="加";
const MINUS="減";
export function couter(state=0, action) {
switch (action.type){
case ADD:
return state+1
case MINUS:
return state-1
default:
return 1
}
}
//store.dispatch({type:'加'});store.dispatch({type:'減'})
//action
export function addFn() {
return { type:ADD }
}
export function minusFn() {
return { type:MINUS }
}
app.js中使用
內部經過屬性獲取store以及相應的函數
const store=this.props.store
點擊的時候要改變狀態 dispatch //addFn() 執行返回的是對象
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props)
}
render() {
const store=this.props.store
const addFn=this.props.addFn
const minusFn=this.props.minusFn
const init=store.getState()
return (
<div className="App">
<h1>你好嗎?</h1>
<p>如今的總數是:{init}</p>
<button onClick={ ()=>store.dispatch( addFn() ) }>加1</button>
<button onClick={ ()=>store.dispatch( minusFn() ) }>減1</button>
</div>
);
}
}
export default App;
運行結果能實現簡單的經過redux管理狀態:
三:redux異步處理 redux-thunk
強制清除緩存 。npm報錯。code爲408(不容許安裝) 這時候執行 npm cache clean --force
處理異步
redux默認狀況下只處理同步,想要處理異步,須要上面安裝的redux-thunk插件
先引入:
import { createStore ,applyMiddleware } from 'redux';
import thunk from 'redux-thunk'
使用applyMiddleware在建立store的時候開啓中間件
const store=createStore(couter ,applyMiddleware(thunk))
以前action是個對象。直接dispatch這個對象就直接修改狀態。store.dispatch({type:MINUS})
export function minusFn() {
return { type:MINUS }
}
action能夠返回函數,使用dispatch提交action
addAsyn() 這個函數能夠返回個函數。
export function addAsyn() {
return dispatch=>{
setTimeout(()=>{
dispatch(addFn())
},2000)
}
dispatch是個參數。setTimeout結束以後手動執行dispatch
入口:index.js
app.js
index.redux.js
多向外暴露個函數
實現效果:
四:react和redux的結合使用
插件:react-redux
不適用subscribe發佈事件
提供provider和connect兩個接口連接react和redux
index.js調整
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore ,applyMiddleware } from 'redux';
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import App from './App';
import { couter } from './index.redux';
import registerServiceWorker from './registerServiceWorker';
const store=createStore(couter , applyMiddleware(thunk))
ReactDOM.render(
(<Provider store={store}>
< App />
</Provider>)
, document.getElementById('root'));
registerServiceWorker();
app.js中
connect負責從外部獲取組件須要的參數。放到props中
import React, { Component } from 'react'; import { connect } from 'react-redux' import {addFn,minusFn,addAsyn} from './index.redux' class App extends Component { render() { const num=this.props.num const addFn=this.props.addFn const minusFn=this.props.minusFn const addAsyn=this.props.addAsyn return ( <div className="App"> <h1>你好嗎?</h1> <p> { num }</p> <button onClick={addFn}>加1</button> <button onClick={minusFn}>減1</button> <button onClick={addAsyn}>異步加1</button> </div> ); } } //num state狀態 映射到屬性裏面 const mapStatetoProps=(state)=>{ return {num:state} } //num 能夠經過props獲取 const actionCreators={addFn,minusFn,addAsyn} //addFn 自動有了dispatch的功能 onClick={addFn} //addFn minusFn minusFn會被映射到props裏面 //this.props.addFn 能夠經過props獲取 App=connect(mapStatetoProps,actionCreators)(App) export default App;
五:@優化
安裝插件,配置package.json介紹:http://www.cnblogs.com/kelly2017/p/7930681.html
import { connect } from 'react-redux' import {addFn,minusFn,addAsyn} from './index.redux' //num state狀態 映射到屬性裏面 // const mapStatetoProps=(state)=>{ // return {num:state} // } //num 能夠經過props獲取 // const actionCreators={addFn,minusFn,addAsyn} //addFn 自動有了dispatch的功能 onClick={addFn} //addFn minusFn minusFn會被映射到props裏面 //this.props.addFn 能夠經過props獲取 //App=connect(mapStatetoProps,actionCreators)(App) //@connect(mapStatetoProps,actionCreators) @connect( (state)=>({num:state}),
//第一個參數,state裏的屬性放到props裏面 {addFn,minusFn,addAsyn}
//方法放到props裏 )
六:多個reducer之間的合併問題
新建一個專門用來合併用的reducer.js 主要的合併的方法 combineReducers
//多個reducer之間的合併 而且返回
import {combineReducers} from 'redux'
//redux提供的用於多個reducer合併的方法
// 裏面是個對象。羅列須要合併的reducer
import { couter } from './index.redux'; //項目中須要的reducer
import { auth } from './Auth.redux'; //項目中須要的reducer
export default combineReducers({couter,auth})
在index.js中不須要以前引入的單個的reducer.直接引入合併以後的就能夠
import reducer from './reducer' import Dashboard from './Dashboard' import registerServiceWorker from './registerServiceWorker'; //以前就一個couter reducer 如今加了一個auth reducer const store=createStore( reducer , applyMiddleware(thunk) ) console.log(store.getState())
打印結果:合併以後的兩個reducer的初始狀態。