1. react-redux
- React-Redux 是 Redux 的官方 React 綁定庫。
- React-Redux 能夠使你的React組件從Redux store中讀取數據,並且向 store 分發 actions 以更新數據。
- React-Redux 並不是 Redux 內置,需要單獨安裝。
- React-Redux 一般會和 Redux 結合一起使用。
react-redux 安裝
$ npm install react-redux
Provider 和 connect
React-Redux 提供<Provider/>
組件,能夠使你的整個app訪問到Redux store中的數據:
App.js:
import React, { Component, Fragment } from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Todolist from './Todolist';
class App extends Component {
render() {
return (
<Provider store={store}>
<Fragment>
<Todolist />
</Fragment>
</Provider>
)
}
}
export default App;
React-Redux提供一個connect
方法能夠讓你把組件和store連接起來。
可以在 connect 方法中定義兩個參數: mapStateToProps
和 mapDispatchToProps
;
-
[mapStateToProps(state, [ownProps]): stateProps] (Function): 如果定義該參數,組件將會監聽 Redux store 的變化。任何時候,只要 Redux store 發生改變,mapStateToProps 函數就會被調用。
-
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function): 如果傳遞的是一個對象,那么每個定義在該對象的函數都將被當作 Redux action creator,對象所定義的方法名將作為屬性名;每個方法將返回一個新的函數,函數中dispatch方法會將 action creator 的返回值作為參數執行。這些屬性會被合並到組件的 props 中。
例如:在組件
import React, { Component } from 'react';
import { connect } from 'react-redux'
class TodoList extends Component {
render() {
... ...
}
}
// 將store里面的state映射給當前組件,成為組件的props
// 只要 Redux store 發生改變,mapStateToProps 函數就會被調用。該
// 回調函數必須返回一個純對象,這個對象會與組件的 props 合並
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
// 將store.dispatch()方法映射到props上
const mapDispatchToProps = (dispatch) => {
return {
ChangeInputValue(e) {
const action = ...
dispatch(action);
},
handleClick() {
const action = ...
dispatch(action);
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);
2. redux-thunk
Action 發出以后,Reducer 立即算出 State,這叫做同步;Action 發出以后,過一段時間再執行 Reducer,這就是異步。
- redux-thunk 是一個常用的 redux 異步 action 中間件。通常用來處理axios請求。
- redux-thunk 中間件可以讓 action 創建函數先不返回一 個action 對象,而是返回一個函數
redux-thunk 用法
$ npm install redux-thunk
import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
const store = createStore(
reducers,
applyMiddleware(thunk)
);
export default store;
applyMiddlewares() 是 Redux 的原生方法,作用是將所有中間件組成一個數組,依次執行。
在 actionCreator.js 中:
// 一般,創建 action 的函數只能返回一個對象
export const initListAction = (list) => {
return {
type: constants.INIT_LIST,
list
}
}
// ---------------------------
// 使用了 redux-thunk, action函數可以返回一個函數
export const getTodoList = () => {
return (dispatch) => {
axios.get('/api/list.json').then(res => {
const { data } = res;
const action = initListAction(data);
dispatch(action);
})
}
}
在 reducer.js 中:
export default (state = defaultState, action) => {
··· ···
if (action.type === constants.INIT_LIST) {
let newState = JSON.parse(JSON.stringify(state));
newState.list = action.list;
return newState;
}
return state;
}
在 Todolist.js 中:
componentDidMount () {
const action = getTodoList();
// 這里取到的action是一個函數,當執行dispatch時,會自動執行該函數
store.dispatch(action);
}